package com.genexususa.eo.google.connection;

import com.genexususa.eo.bing.CampaignManagementServiceClasses.Campaign;
import com.genexususa.eo.google.data.*;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.api.ads.adwords.lib.jaxb.v201406.*;
import com.google.api.ads.adwords.lib.utils.ReportDownloadResponse;
import com.google.api.ads.adwords.lib.utils.ReportDownloadResponseException;
import com.google.api.ads.adwords.lib.utils.ReportException;
import com.google.api.ads.adwords.lib.utils.v201406.ReportDownloader;

import com.google.api.ads.common.lib.auth.OfflineCredentials;
import com.google.api.ads.common.lib.utils.Streams;
import com.google.api.client.auth.oauth2.Credential;
import com.google.common.collect.Lists;
import org.apache.log4j.Logger;
import org.joda.time.DateTime;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;


public class ReportManager {

    private String _clientId;

    private static final int PAGE_SIZE = 5000;

    public void SetClientId(String clientId) {
        this._clientId = clientId;
    }

    public String GetClientId() {
        return _clientId;
    }

    public void Finalize() {

        SessionController sc = SessionController.getInstance();
        sc.RemoveSession(_clientId);
    }

    public void GetTotalReport(String filePath) {
        AccountManager am = new AccountManager();
        ArrayList<GA_Account> accounts = am.GetAllAccounts();

        for (GA_Account account : accounts) {
            this.GetTotalReportForClient(account.AccountGxId.toString(), filePath);
        }
    }

    public void GetTotalReportThreaded(String clientIds, String filePath, Long waitTotalReport){
        String[] clientIdsArray = clientIds.split(";");
        //AccountManager am = new AccountManager();
        //ArrayList<Long> accountIds = am.GetAllAccountId();

        ArrayList<Thread> threads = new ArrayList<Thread>();

        for(String clientId : clientIdsArray){

            GetTotalReportForClientThread totalReport = new GetTotalReportForClientThread(Long.parseLong(clientId), filePath);
            totalReport.start();
            threads.add(totalReport);
            try {
                Thread.sleep(waitTotalReport);
            }catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }


        for (Thread thread : threads){
            try{
                thread.join();
            }catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
    }

    public void GetTotalReportForClientsThreaded(String clientIds, String filePath, Long waitBetweenRequests){

        String[] clientIdsArray = clientIds.split(";");

        ArrayList<Thread> threads = new ArrayList<Thread>();

        for(String clientId : clientIdsArray){


            GetTotalReportClientThread totalReport = new GetTotalReportClientThread(clientId, filePath);
            totalReport.run();
            threads.add(totalReport);
            try {
                Thread.sleep(waitBetweenRequests);
            }catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }


        for (Thread thread : threads){
            try{
                thread.join();
            }catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }

    }

    public void GetTotalReportForClient(String accountId, String filePath) {
        CampaignManager cm = new CampaignManager();
        GA_Report report = new GA_Report();
        cm.SetClientId(accountId);
        ArrayList<GA_CampaignStats> stats = cm.GetCampaignStats();
        for (GA_CampaignStats stat : stats) {
            CampaignReport campaignReport = new CampaignReport();
            campaignReport.AdServingOptimizationStatus = stat.AdServingOptimizationStatus;
            campaignReport.BidCeiling = stat.BidCeiling;
            campaignReport.BiddingStrategyType = stat.BiddingStrategyType;
            campaignReport.BidType = stat.BidType;
            campaignReport.BudgetId = stat.BudgetId;
            campaignReport.EndDate = stat.EndDate;
            campaignReport.EnhancedCpcEnabled = stat.EnhancedCpcEnabled;
            campaignReport.FrequencyCapMaxImpressions = stat.FrequencyCapMaxImpressions;
            campaignReport.Id = stat.Id;
            campaignReport.Level = stat.Level;
            campaignReport.Name = stat.Name;
            campaignReport.PricingMode = stat.PricingMode;
            campaignReport.StartDate = stat.StartDate;
            campaignReport.Status = stat.Status;
            campaignReport.TargetContentNetwork = stat.TargetContentNetwork;
            campaignReport.TargetGoogleSearch = stat.TargetGoogleSearch;
            campaignReport.TargetPartnerSearchNetwork = stat.TargetPartnerSearchNetwork;
            campaignReport.TargetSearchNetwork = stat.TargetSearchNetwork;
            campaignReport.TimeUnit = stat.TimeUnit;
            campaignReport.GeoTargetNegativeType = stat.GeoTargetNegativeType;
            campaignReport.GeoTargetPositiveType = stat.GeoTargetPositiveType;
            campaignReport.KeywordMatch = stat.KeywordMatch;
            campaignReport.RealTimeBidding = stat.RealTimeBidding;
            campaignReport.AdvertisingChannelType = stat.AdvertisingChannelType;
            campaignReport.BiddingStrategyId = stat.BiddingStrategyId;
            campaignReport.BiddingStrategyName = stat.BiddingStrategyName;

            report.Campaigns.add(campaignReport);
        }

        AdExtensionManager adExtManager = new AdExtensionManager();
        ArrayList<AdExtensionLocationReport> extensionLocations = adExtManager.GetAdExtensionLocationReport(accountId);

        ArrayList<SitelinksReport> sitelinks = adExtManager.GetFeedItemsSitelinksReport(accountId);
        report.Sitelinks = sitelinks;

        ArrayList<LocationExtensionReport> locationExtensions = adExtManager.GetFeedItemsLocationExtensionReport(accountId);
        report.LocationExtensions = locationExtensions;



        ArrayList<CallsAdExtensionReport> calls = adExtManager.GetFeedItemsAdExtensionsCallsReport(accountId);
        report.Calls = calls;

        /*ConversionTrackerManager conversionManager = new ConversionTrackerManager();
        ArrayList<AdCallMetricsConversionReport> callMetrics = conversionManager.GetAdCallMetricsConversionReport(accountId);
        report.AdCallMetricsConversions = callMetrics;  */

        CampaignTargetingManager ctm = new CampaignTargetingManager();
        ArrayList<PlatformReport> platforms = ctm.GetCampaignDevices(accountId);
        ArrayList<LanguageReport> languages = ctm.GetCampaignLanguages(accountId);

        CampaignCriterionManager ccm = new CampaignCriterionManager();
        ArrayList<KeywordReport> campaignKeywords = ccm.GetKeywords(accountId, new ArrayList<String>());
        ArrayList<CampaignAdScheduleReport> campaignAdSchedules = ccm.GetAdSchedules(accountId, new ArrayList<String>());

        AdGroupManager adm = new AdGroupManager();
        ArrayList<AdGroupReport> adGroups = adm.GetAdGroupStats(accountId);

        ArrayList<ProximityReport> proximities = ccm.GetProximities(accountId);
        ArrayList<LocationReport> locations = ccm.GetLocations(accountId);
        LocationCriterionManager lcm = new LocationCriterionManager();
        lcm.SetClientId(accountId);
        lcm.getLocationsExtraData(locations);

        AdsManager adsManager = new AdsManager();

        ArrayList<TextAdReport> textAds = adsManager.GetTextAds(accountId);
        ArrayList<ImageAdReport> imageAds = adsManager.GetImageAds(accountId);
        ArrayList<MobileImageAdReport> mobileImageAds = adsManager.GetMobileImageAds(accountId);

        AdGroupCriterionManager acm = new AdGroupCriterionManager();
        ArrayList<AdGroupKeywordReport> adGroupKeywords = acm.GetAdGroupKeywords(accountId);

        report.Budgets = cm.GetBudgetStats();

        AccountManager am = new AccountManager();

        report.Account = am.GetAccountReport(accountId);

        FeedManager fm = new FeedManager();

        report.Feeds = fm.GetAllFeedsReport(accountId);

        // ngonzalez | 01.29.2014 |
        ArrayList<AdGroupPlacementReport> adGroupPlacementReports = acm.GetAdGroupPlacements(accountId);
        ArrayList<AdGroupTopicReport> adGroupTopicReports = acm.GetAdGroupTopics(accountId);
        ArrayList<AdGroupInterestReport> adGroupInterestReports = acm.GetAdGroupInterests(accountId);
        ArrayList<AdGroupGenderReport> adGroupGenderReports = acm.GetAdGroupGenders(accountId);
        ArrayList<AdGroupAgeReport> adGroupAgeReports = acm.GetAdGroupAges(accountId);

        ArrayList<GA_SitelinksFeedItem> sitelinksFeedItems = fm.GetSitelinksFeedItemReport(accountId);
        report.SitelinksFeedItems = sitelinksFeedItems;

        ArrayList<GA_LocationExtensionsFeedItem> locationExtensionsFeedItems = fm.GetLocationExtensionsFeedItemReport(accountId);
        report.LocationExtensionsFeedItems = locationExtensionsFeedItems;

        ArrayList<GA_CallsFeedItem> callsFeedItems = fm.GetCallsFeedItemReport(accountId);
        report.CallsFeedItems = callsFeedItems;

        //ConversionTrackerManager ctm = new ConversionTrackerManager();

        //report.ConversionTrackers = ctm.GetConversionTrackerStats(accountId);

        // ngonzalez | 11.25.2013 | group obtained totals by campaign
        for (CampaignReport cr : report.Campaigns){
            Long campaignId = cr.Id;

            // AdGroups
            for(AdGroupReport adGroupReport : adGroups){
                if(adGroupReport.CampaignId.equals(campaignId)){

                    // AdGroupKeywords
                    for(AdGroupKeywordReport adGroupKeywordReport :  adGroupKeywords){
                        if(adGroupKeywordReport.AdGroupId.equals(adGroupReport.Id)){
                            adGroupReport.AdGroupKeywords.add(adGroupKeywordReport);
                        }
                    }

                    // TextAds
                    for(TextAdReport textAdReport : textAds){
                        if(textAdReport.AdGroupId.equals(adGroupReport.Id)){
                            adGroupReport.TextAds.add(textAdReport);
                        }
                    }

                    // ImageAds
                    for(ImageAdReport imageAdReport : imageAds){
                        if(imageAdReport.AdGroupId.equals(adGroupReport.Id)){
                            adGroupReport.ImageAds.add(imageAdReport);
                        }
                    }

                    // MobileImageAds
                    for(MobileImageAdReport mobileImageAdReport : mobileImageAds){
                        if(mobileImageAdReport.AdGroupId.equals(adGroupReport.Id)){
                            adGroupReport.MobileImageAds.add(mobileImageAdReport);
                        }
                    }

                    // ngonzalez | 01.29.2014 |
                    for(AdGroupPlacementReport placementReport : adGroupPlacementReports){
                        if(placementReport.AdGroupId.equals(adGroupReport.Id)){
                            adGroupReport.AdGroupPlacements.add(placementReport);
                        }
                    }

                    for(AdGroupTopicReport adGroupTopicReport : adGroupTopicReports){
                        if(adGroupTopicReport.AdGroupId.equals(adGroupReport.Id)){
                            adGroupReport.AdGroupTopics.add(adGroupTopicReport);
                        }
                    }

                    for(AdGroupInterestReport adGroupInterestReport : adGroupInterestReports){
                        if(adGroupInterestReport.AdGroupId.equals(adGroupReport.Id)){
                            adGroupReport.AdGroupInterests.add(adGroupInterestReport);
                        }
                    }

                    for(AdGroupGenderReport adGroupGenderReport : adGroupGenderReports){
                        if(adGroupGenderReport.AdGroupId.equals(adGroupReport.Id)){
                            adGroupReport.AdGroupGenders.add(adGroupGenderReport);
                        }
                    }

                    for(AdGroupAgeReport adGroupAgeReport : adGroupAgeReports){
                        if(adGroupAgeReport.AdGroupId.equals(adGroupReport.Id)){
                            adGroupReport.AdGroupAges.add(adGroupAgeReport);
                        }
                    }

                    cr.AdGroups.add(adGroupReport);
                }
            }

            // ExtensionLocations
            for(AdExtensionLocationReport adExtensionLocationReport : extensionLocations){
                if(adExtensionLocationReport.CampaignId.equals(campaignId)){
                    cr.ExtensionLocations.add(adExtensionLocationReport);
                }
            }

            // MobileExtensions
            /*for(AdExtensionMobileReport adExtensionMobileReport : mobileExtensions){
                if(adExtensionMobileReport.CampaignId.equals(campaignId)){
                    cr.MobileExtensions.add(adExtensionMobileReport);
                }
            }  */

            // SitelinksExtensions
           /* for(AdExtensionSitelinksReport adExtensionSitelinksReport : sitelinksExtensions){
                if(adExtensionSitelinksReport.CampaignId.equals(campaignId)){
                    cr.SitelinksExtensions.add(adExtensionSitelinksReport);
                }
            }    */

            // Languages
            for(LanguageReport languageReport : languages){
                if(languageReport.CampaignId.equals(campaignId)){
                    cr.Languages.add(languageReport);
                }
            }

            // Platforms
            for(PlatformReport platformReport : platforms){
                if(platformReport.CampaignId.equals(campaignId)){
                    cr.Platforms.add(platformReport);
                }
            }

            // Keywords
            for(KeywordReport keywordReport : campaignKeywords){
                if(keywordReport.CampaignId.equals(campaignId)){
                    cr.Keywords.add(keywordReport);
                }
            }

            // AdSchedules
            for(CampaignAdScheduleReport campaignAdScheduleReport : campaignAdSchedules){
                if(campaignAdScheduleReport.CampaignId.equals(campaignId)){
                    cr.AdSchedules.add(campaignAdScheduleReport);
                }
            }

            // Proximities
            for(ProximityReport proximityReport : proximities){
                if(proximityReport.CampaignId.equals(campaignId)){
                    cr.Proximities.add(proximityReport);
                }
            }

            // Locations
            for(LocationReport locationReport : locations){
                if(locationReport.CampaignId.equals(campaignId)){
                    cr.Locations.add(locationReport);
                }
            }
        }

        try {

            String result = "";

            JAXBContext contextObj = JAXBContext.newInstance(GA_Report.class);

            Marshaller marshallerObj = contextObj.createMarshaller();
            marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            StringWriter sw = new StringWriter();

            marshallerObj.marshal(report, sw);
            result = sw.getBuffer().toString();
            //System.out.println(result);

            FileWriter fw = new FileWriter(filePath + File.separator + accountId + ".xml");
            BufferedWriter bw = new BufferedWriter(fw);

            bw.write(result);
            bw.flush();
            bw.close();

        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    public void GetTotalReportForClientThreaded(String accountId, String filePath){

        ArrayList<Thread> threads = new ArrayList<Thread>();

        GA_Report report = new GA_Report();

        GetCampaignStatsThread campaignStats = new GetCampaignStatsThread(Long.parseLong(accountId));
        campaignStats.start();
        threads.add(campaignStats);

        GetAdExtensionLocationReportThread adExtensionLocationReport = new GetAdExtensionLocationReportThread(Long.parseLong(accountId));
        adExtensionLocationReport.start();
        threads.add(adExtensionLocationReport);

        GetSitelinksReportThread sitelinksReport = new GetSitelinksReportThread(Long.parseLong(accountId));
        sitelinksReport.start();
        threads.add(sitelinksReport);

        GetLocationExtensionReportThread locationExtensionReport = new GetLocationExtensionReportThread(Long.parseLong(accountId));
        locationExtensionReport.start();
        threads.add(locationExtensionReport);

        GetCallsAdExtensionReportThread callsAdExtensionReport = new GetCallsAdExtensionReportThread(Long.parseLong(accountId));
        callsAdExtensionReport.start();
        threads.add(callsAdExtensionReport);

        GetCampaignProximitiesReportThread proximitiesReport = new GetCampaignProximitiesReportThread((Long.parseLong(accountId)));
        proximitiesReport.start();
        threads.add(proximitiesReport);

        GetCampaignLocationsReportThread locationsReport = new GetCampaignLocationsReportThread((Long.parseLong(accountId)));
        locationsReport.start();
        threads.add(locationsReport);

        GetCampaignAdGroupReportThread adGroupReport = new GetCampaignAdGroupReportThread(Long.parseLong(accountId));
        adGroupReport.start();
        threads.add(adGroupReport);

        GetCampaignKeywordReportThread keywordReport = new GetCampaignKeywordReportThread(Long.parseLong(accountId));
        keywordReport.start();
        threads.add(keywordReport);

        GetCampaignAdScheduleReportThread campaignAdScheduleReport = new GetCampaignAdScheduleReportThread(Long.parseLong(accountId));
        campaignAdScheduleReport.start();
        threads.add(campaignAdScheduleReport);

        GetPlatformReportThread platformReport = new GetPlatformReportThread(Long.parseLong(accountId));
        platformReport.start();
        threads.add(platformReport);

        GetLanguageReportThread languageReport = new GetLanguageReportThread(Long.parseLong(accountId));
        languageReport.start();
        threads.add(languageReport);

        GetAllFeedsReportThread feedsReport = new GetAllFeedsReportThread(Long.parseLong(accountId));
        feedsReport.start();
        threads.add(feedsReport);

        GetAccountStatsReportThread accountReport = new GetAccountStatsReportThread(Long.parseLong(accountId));
        accountReport.start();
        threads.add(accountReport);

        GetBudgetReportThread budgetReport = new GetBudgetReportThread(Long.parseLong(accountId));
        budgetReport.start();
        threads.add(budgetReport);

        GetAdGroupKeywordsReportThread adGroupKeywordsReport = new GetAdGroupKeywordsReportThread(Long.parseLong(accountId));
        adGroupKeywordsReport.start();
        threads.add(adGroupKeywordsReport);

        GetImageAdsReportThread imageAdsReport = new GetImageAdsReportThread(Long.parseLong(accountId));
        imageAdsReport.start();
        threads.add(imageAdsReport);

        GetMobileImageAdsReportThread mobileImageAdsReport = new GetMobileImageAdsReportThread(Long.parseLong(accountId));
        mobileImageAdsReport.start();
        threads.add(mobileImageAdsReport);

        GetTextAdsReportThread textAdsReport = new GetTextAdsReportThread(Long.parseLong(accountId));
        textAdsReport.start();
        threads.add(textAdsReport);

        GetCallsFeedItemsReportThread callsReport = new GetCallsFeedItemsReportThread(Long.parseLong(accountId));
        callsReport.start();
        threads.add(callsReport);

        GetLocationExtensionsFeedItemsReportThread locationExtensionsFeedItemsReport = new GetLocationExtensionsFeedItemsReportThread(Long.parseLong(accountId));
        locationExtensionsFeedItemsReport.start();
        threads.add(locationExtensionsFeedItemsReport);

        GetSitelinksFeedItemsReportThread sitelinksFeedItemsReport = new GetSitelinksFeedItemsReportThread(Long.parseLong(accountId));
        sitelinksFeedItemsReport.start();
        threads.add(sitelinksFeedItemsReport);

        GetAdGroupAgeReportThread adGroupAgeReports = new GetAdGroupAgeReportThread(Long.parseLong(accountId));
        adGroupAgeReports.start();
        threads.add(adGroupAgeReports);

        GetAdGroupGenderReportThread adGroupGenderReports = new GetAdGroupGenderReportThread(Long.parseLong(accountId));
        adGroupGenderReports.start();
        threads.add(adGroupGenderReports);

        GetAdGroupInterestReportThread adGroupInterestReports = new GetAdGroupInterestReportThread(Long.parseLong(accountId));
        adGroupInterestReports.start();
        threads.add(adGroupInterestReports);

        GetAdGroupTopicReportThread adGroupTopicReports = new GetAdGroupTopicReportThread(Long.parseLong(accountId));
        adGroupTopicReports.start();
        threads.add(adGroupTopicReports);

        GetAdGroupPlacementsReportThread adGroupPlacementsReports = new GetAdGroupPlacementsReportThread(Long.parseLong(accountId));
        adGroupPlacementsReports.start();
        threads.add(adGroupPlacementsReports);

        for (Thread thread : threads){
            try {
                thread.join();

                if (thread.getClass() == GetCampaignStatsThread.class) {
                    report.Campaigns = campaignStats.GetCampaignStats();
                }

                if (thread.getClass() == GetAdExtensionLocationReportThread.class) {
                    //report.Campaigns = campaignStats.GetCampaignStats();
                }

                if (thread.getClass() == GetSitelinksReportThread.class) {
                    report.Sitelinks = sitelinksReport.GetSitelinksReportsThreaded();
                }

                if (thread.getClass() == GetLocationExtensionReportThread.class) {
                    report.LocationExtensions = locationExtensionReport.GetLocationExtensionReportsThreaded();
                }

                if (thread.getClass() == GetCallsAdExtensionReportThread.class) {
                    report.Calls = callsAdExtensionReport.GetCallsAdExtensionReportsThreaded();
                }

                if (thread.getClass() == GetAllFeedsReportThread.class){
                    report.Feeds = feedsReport.GetFeedReports();
                }

                if (thread.getClass() == GetAccountStatsReportThread.class){
                    report.Account = accountReport.GetAccountReport();
                }

                if (thread.getClass() == GetBudgetReportThread.class){
                    report.Budgets = budgetReport.GetBudgetReportThreaded();
                }

                if (thread.getClass() == GetCallsFeedItemsReportThread.class){
                    report.CallsFeedItems = callsReport.GetCallsReportThread();
                }

                if (thread.getClass() == GetLocationExtensionsFeedItemsReportThread.class){
                    report.LocationExtensionsFeedItems = locationExtensionsFeedItemsReport.GetLocationExtensionsReportThread();
                }

                if (thread.getClass() == GetSitelinksFeedItemsReportThread.class){
                    report.SitelinksFeedItems = sitelinksFeedItemsReport.GetSitelinksFeedItemsReportThread();
                }

            } catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }

        }


        for (CampaignReport cr : report.Campaigns){
            Long campaignId = cr.Id;

            // AdGroups
            for(AdGroupReport adGroupRep : adGroupReport.GetAdGroupReportThreaded()){
                if(adGroupRep.CampaignId.equals(campaignId)){

                    // AdGroupKeywords
                    for(AdGroupKeywordReport adGroupKeywordReport :  adGroupKeywordsReport.GetAdGroupKeywordReportThreaded()){
                        if(adGroupKeywordReport.AdGroupId.equals(adGroupRep.Id)){
                            adGroupRep.AdGroupKeywords.add(adGroupKeywordReport);
                        }
                    }

                    // TextAds
                    for(TextAdReport textAdReport : textAdsReport.GetTextAdsReportThreaded()){
                        if(textAdReport.AdGroupId.equals(adGroupRep.Id)){
                            adGroupRep.TextAds.add(textAdReport);
                        }
                    }

                    // ImageAds
                    for(ImageAdReport imageAdReport : imageAdsReport.GetImageAdsReportThreaded()){
                        if(imageAdReport.AdGroupId.equals(adGroupRep.Id)){
                            adGroupRep.ImageAds.add(imageAdReport);
                        }
                    }

                    // MobileImageAds
                    for(MobileImageAdReport mobileImageAdReport : mobileImageAdsReport.GetMobileImageAdsReportThreaded()){
                        if(mobileImageAdReport.AdGroupId.equals(adGroupRep.Id)){
                            adGroupRep.MobileImageAds.add(mobileImageAdReport);
                        }
                    }

                    // ngonzalez | 01.29.2014 |
                    for(AdGroupPlacementReport placementReport : adGroupPlacementsReports.GetAdGroupPlacementsReport()){
                        if(placementReport.AdGroupId.equals(adGroupRep.Id)){
                            adGroupRep.AdGroupPlacements.add(placementReport);
                        }
                    }

                    for(AdGroupTopicReport adGroupTopicReport : adGroupTopicReports.GetAdGroupTopicsReport()){
                        if(adGroupTopicReport.AdGroupId.equals(adGroupRep.Id)){
                            adGroupRep.AdGroupTopics.add(adGroupTopicReport);
                        }
                    }

                    for(AdGroupInterestReport adGroupInterestReport : adGroupInterestReports.GetAdGroupInterestReportsThreaded()){
                        if(adGroupInterestReport.AdGroupId.equals(adGroupRep.Id)){
                            adGroupRep.AdGroupInterests.add(adGroupInterestReport);
                        }
                    }

                    for(AdGroupGenderReport adGroupGenderReport : adGroupGenderReports.GetAdGroupGenderReportThreaded()){
                        if(adGroupGenderReport.AdGroupId.equals(adGroupRep.Id)){
                            adGroupRep.AdGroupGenders.add(adGroupGenderReport);
                        }
                    }

                    for(AdGroupAgeReport adGroupAgeReport : adGroupAgeReports.GetAdGroupAgeReportThreaded()){
                        if(adGroupAgeReport.AdGroupId.equals(adGroupRep.Id)){
                            adGroupRep.AdGroupAges.add(adGroupAgeReport);
                        }
                    }

                    cr.AdGroups.add(adGroupRep);
                }
            }

            // ExtensionLocations
            for(AdExtensionLocationReport adExtensionLocation : adExtensionLocationReport.GetAdExtensionLocationReportsThreaded()){
                if(adExtensionLocation.CampaignId.equals(campaignId)){
                    cr.ExtensionLocations.add(adExtensionLocation);
                }
            }
            // Languages
            for(LanguageReport language : languageReport.GetLanguageReportsThreaded()){
                if(language.CampaignId.equals(campaignId)){
                    cr.Languages.add(language);
                }
            }

            // Platforms
            for(PlatformReport platform : platformReport.GetPlatformReportsThreaded()){
                if(platform.CampaignId.equals(campaignId)){
                    cr.Platforms.add(platform);
                }
            }

            // Keywords
            for(KeywordReport keyword : keywordReport.GetKeywordReportThreaded()){
                if(keyword.CampaignId.equals(campaignId)){
                    cr.Keywords.add(keyword);
                }
            }

            // AdSchedules
            for(CampaignAdScheduleReport adSchedule : campaignAdScheduleReport.GetAdScheduleReportThreaded()){
                if(adSchedule.CampaignId.equals(campaignId)){
                    cr.AdSchedules.add(adSchedule);
                }
            }

            // Proximities
            for(ProximityReport proximity : proximitiesReport.GetProximitiesReportThreaded()){
                if(proximity.CampaignId.equals(campaignId)){
                    cr.Proximities.add(proximity);
                }
            }

            // Locations
            for(LocationReport location : locationsReport.GetLocationsReportThreaded()){
                if(location.CampaignId.equals(campaignId)){
                    cr.Locations.add(location);
                }
            }
        }


        try {

            String result = "";

            JAXBContext contextObj = JAXBContext.newInstance(GA_Report.class);

            Marshaller marshallerObj = contextObj.createMarshaller();
            marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            StringWriter sw = new StringWriter();

            marshallerObj.marshal(report, sw);
            result = sw.getBuffer().toString();
            //System.out.println(result);

            FileWriter fw = new FileWriter(filePath + File.separator + accountId + ".xml");
            BufferedWriter bw = new BufferedWriter(fw);

            bw.write(result);
            bw.flush();
            bw.close();

        } catch (Exception exc) {
            exc.printStackTrace();
        }




    }

    public void GetAllReportsThreaded(String locationFile, String date, Long waitBetweenRequests){
        AccountManager am = new AccountManager();
        ArrayList<GA_Account> accounts = am.GetAllAccounts();
        for (GA_Account account : accounts) {
            Long clientId = account.AccountGxId;
            File location = new File(locationFile + File.separator + clientId + "-" + date);

            if (!location.exists()) {

                boolean isOK = location.mkdir();

                if (isOK) {

                    GetCampaignReportThread campaignReport = new GetCampaignReportThread(clientId, locationFile, date);
                    campaignReport.start();

                    try {
                        Thread.sleep(waitBetweenRequests);
                    } catch (InterruptedException e) {
                        //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                    }


                }
            }

        }

    }

    public boolean GetAllReportsThreadedForClients(String clientIds, String locationFile, String date, Long waitBetweenRequests) {

        String[] clientIdsArray = clientIds.split(";");

        ArrayList<Thread> threads = new ArrayList<Thread>();


        for(String clientId : clientIdsArray){
            File location = new File(locationFile + File.separator + clientId + "-" + date);

            if (!location.exists()) {

                boolean isOK = location.mkdir();

                if (isOK) {

                    GetCampaignReportThread campaignReport = new GetCampaignReportThread(Long.parseLong(clientId), locationFile, date);
                    campaignReport.start();
                    threads.add(campaignReport);

                    try {
                        Thread.sleep(waitBetweenRequests);
                    } catch (InterruptedException e) {
                        //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                    }


                }
            }
        }


        for(Thread thread : threads){

            try {
                thread.join();

            } catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }

        }


        return true;

    }

    public void GetAllReports(String locationFile, String date) {

        AccountManager am = new AccountManager();
        ArrayList<GA_Account> accounts = am.GetAllAccounts();

        for (GA_Account account : accounts) {
            Long clientId = account.AccountGxId;
            File location = new File(locationFile + File.separator + clientId + "-" + date);

            if (!location.exists()) {

                boolean isOK = location.mkdir();

                if (isOK) {

                    try {

                        GetCampaignReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                        //GetAccountReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                        GetAdGroupReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                        GetAdReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                        //GetAdExtensionReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                        GetKeywordReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                        //GetCampaignKeywordsReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);

                    } catch (Exception exc) {
                        exc.printStackTrace();
                    }

                }

            }

        }


    }

    public void GetAllReportsForClient(String clientId, String locationFile, String date) {

        AccountManager am = new AccountManager();
        //ArrayList<Long> accountIds = am.GetAllAccountId();

        File location = new File(locationFile + File.separator + clientId + "-" + date);

        boolean isOK = location.exists() || location.mkdir();

        if (isOK) {

            try {

                GetCampaignReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                //GetAccountReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                GetAdGroupReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                GetAdReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                //GetAdExtensionReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                GetKeywordReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                //GetCampaignKeywordsReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);

            } catch (Exception exc) {
                exc.printStackTrace();
            }
        } else {
            System.out.println("Folder " + location.getAbsolutePath() + " not found");
        }
    }

    public void GetCampaignSearchReport(String locationFile, String startDate, String endDate){

        try {

            Credential oAuth2Credential = new OfflineCredentials.Builder()
                    .forApi(OfflineCredentials.Api.ADWORDS)
                    .fromFile()
                    .build()
                    .generateCredential();

            AdWordsSession session = new AdWordsSession.Builder()
                    .fromFile()
                    .withOAuth2Credential(oAuth2Credential)
                    .build();


            session.setClientCustomerId(this.GetClientId());

            com.google.api.ads.adwords.lib.jaxb.v201406.Selector selector = new com.google.api.ads.adwords.lib.jaxb.v201406.Selector();
            selector.getFields().addAll(Lists.newArrayList(
                    "CampaignId",
                    "ExternalCustomerId",
                    "SearchBudgetLostImpressionShare",
                    "SearchImpressionShare",
                    "SearchRankLostImpressionShare"
            ));

            DateRange dateRange = new DateRange();
            dateRange.setMin(startDate.replaceAll("-",""));
            dateRange.setMax(endDate.replaceAll("-",""));

            selector.setDateRange(dateRange);

            // Location to download report to.
            String reportFile = locationFile + File.separatorChar + "CampaignSearchReport-" + startDate + "-" + endDate + ".xml";

            // Create predicates.
            /*com.google.api.ads.adwords.lib.jaxb.v201309.Predicate campaignIdPredicate =
                    new com.google.api.ads.adwords.lib.jaxb.v201309.Predicate();
            campaignIdPredicate.setField("CampaignId");
            campaignIdPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201309.PredicateOperator.IN);
            campaignIdPredicate.getValues().addAll(Lists.newArrayList(campaignId.toString()));
            selector.getPredicates().addAll(Lists.newArrayList(campaignIdPredicate));*/


            // Create report definition.
            ReportDefinition reportDefinition = new ReportDefinition();
            reportDefinition.setReportName("Campaign performance report #" + startDate + "-" + endDate);
            reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.CUSTOM_DATE);
            reportDefinition.setReportType(ReportDefinitionReportType.CAMPAIGN_PERFORMANCE_REPORT);
            reportDefinition.setDownloadFormat(DownloadFormat.XML);
            // Enable to allow rows with zero impressions to show.
            reportDefinition.setIncludeZeroImpressions(true);
            reportDefinition.isIncludeZeroImpressions();
            reportDefinition.setSelector(selector);

            try {
                // Set the property api.adwords.reportDownloadTimeout or call
                // ReportDownloader.setReportDownloadTimeout to set a timeout (in milliseconds)
                // for CONNECT and READ in report downloads.

                ReportDownloadResponse response =
                        new ReportDownloader(session).downloadReport(reportDefinition);

                FileOutputStream fos = new FileOutputStream(new File(reportFile));
                Streams.copy(response.getInputStream(), fos);
                fos.close();
                System.out.println("Report successfully downloaded: " + reportFile);
            } catch (ReportDownloadResponseException e) {
                System.out.println("Report was not downloaded. " + e.toString());
            }


        }catch(Exception exc){

            System.out.println(exc.getMessage());
            exc.printStackTrace();

        }

    }

    public void GetAccountSearchReport(String locationFile, String startDate, String endDate){

        try {

            Credential oAuth2Credential = new OfflineCredentials.Builder()
                    .forApi(OfflineCredentials.Api.ADWORDS)
                    .fromFile()
                    .build()
                    .generateCredential();

            AdWordsSession session = new AdWordsSession.Builder()
                    .fromFile()
                    .withOAuth2Credential(oAuth2Credential)
                    .build();

            session.setClientCustomerId(this.GetClientId());

            com.google.api.ads.adwords.lib.jaxb.v201406.Selector selector = new com.google.api.ads.adwords.lib.jaxb.v201406.Selector();
            selector.getFields().addAll(Lists.newArrayList(
                    "SearchBudgetLostImpressionShare",
                    "SearchImpressionShare",
                    "SearchRankLostImpressionShare"
            ));

            DateRange dateRange = new DateRange();
            dateRange.setMin(startDate.replaceAll("-",""));
            dateRange.setMax(endDate.replaceAll("-",""));

            selector.setDateRange(dateRange);

            // Location to download report to.
            String reportFile = locationFile + File.separatorChar + "AccountSearchReport-" + startDate + "-" + endDate + ".xml";

            // Create predicates.
            /*com.google.api.ads.adwords.lib.jaxb.v201302.Predicate campaignIdPredicate =
                    new com.google.api.ads.adwords.lib.jaxb.v201302.Predicate();
            campaignIdPredicate.setField("CampaignId");
            campaignIdPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201302.PredicateOperator.IN);
            campaignIdPredicate.getValues().addAll(Lists.newArrayList(campaignId.toString()));
            selector.getPredicates().addAll(Lists.newArrayList(campaignIdPredicate));*/


            // Create report definition.
            ReportDefinition reportDefinition = new ReportDefinition();
            reportDefinition.setReportName("Account performance report #" + startDate + "-" + endDate);
            reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.CUSTOM_DATE);
            reportDefinition.setReportType(ReportDefinitionReportType.ACCOUNT_PERFORMANCE_REPORT);
            reportDefinition.setDownloadFormat(DownloadFormat.XML);
            // Enable to allow rows with zero impressions to show.
            reportDefinition.setIncludeZeroImpressions(true);
            reportDefinition.isIncludeZeroImpressions();
            reportDefinition.setSelector(selector);

            try {
                // Set the property api.adwords.reportDownloadTimeout or call
                // ReportDownloader.setReportDownloadTimeout to set a timeout (in milliseconds)
                // for CONNECT and READ in report downloads.

                ReportDownloadResponse response =
                        new ReportDownloader(session).downloadReport(reportDefinition);

                FileOutputStream fos = new FileOutputStream(new File(reportFile));
                Streams.copy(response.getInputStream(), fos);
                fos.close();
                System.out.println("Report successfully downloaded: " + reportFile);
            } catch (ReportDownloadResponseException e) {
                System.out.println("Report was not downloaded. " + e.toString());
            }
        } catch (Exception exc) {
            System.out.println(exc.getMessage());
            exc.printStackTrace();
        }
    }

    public void GetAllProximitiesAndLanguages(String filePath){
        AccountManager am = new AccountManager();
        ArrayList<GA_Account> accounts = am.GetAllAccounts();

        for (GA_Account account : accounts) {
            this.GetAllProximitiesAndLanguagesForClient(account.AccountGxId.toString(), filePath);
        }
    }

    public void GetAllProximitiesAndLanguagesForClient(String clientId, String filePath){

        GA_Report report = new GA_Report();
        CampaignCriterionManager ccm = new CampaignCriterionManager();
        ccm.SetClientId(clientId);
        ArrayList<ProximityReport> proximities = ccm.GetProximities(clientId);
        CampaignTargetingManager ctm = new CampaignTargetingManager();
        ArrayList<PlatformReport> platforms = ctm.GetCampaignDevices(clientId);
        ArrayList<LanguageReport> languages = ctm.GetCampaignLanguages(clientId);

        try {

            String result = "";

            JAXBContext contextObj = JAXBContext.newInstance(GA_Report.class);

            Marshaller marshallerObj = contextObj.createMarshaller();
            marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            StringWriter sw = new StringWriter();

            marshallerObj.marshal(report, sw);
            result = sw.getBuffer().toString();
            //System.out.println(result);

            FileWriter fw = new FileWriter(filePath + File.separator + clientId + ".xml");
            BufferedWriter bw = new BufferedWriter(fw);

            bw.write(result);
            bw.flush();
            bw.close();

        } catch (Exception exc) {
            exc.printStackTrace();
        }


    }

    protected void GetCampaignReport(String clientId, String locationFile, String date) throws Exception {

        Credential oAuth2Credential = new OfflineCredentials.Builder()
                .forApi(OfflineCredentials.Api.ADWORDS)
                .fromFile()
                .build()
                .generateCredential();

        AdWordsSession session = new AdWordsSession.Builder()
                .fromFile()
                .withOAuth2Credential(oAuth2Credential)
                .build();

        session.setClientCustomerId(clientId);

        com.google.api.ads.adwords.lib.jaxb.v201406.Selector selector = new com.google.api.ads.adwords.lib.jaxb.v201406.Selector();
        selector.getFields().addAll(Lists.newArrayList(
                "CampaignId",
                "Id",
                //"Status",
                "Clicks",
                "Cost",
                "Impressions",
                //"AverageCpc",
                //"AverageCpm",
                "AveragePosition",
                //"Ctr",
                //"ConversionRate",
                "Conversions",
                //"CostPerConversion",/*,
                /*"AdNetworkType2",*/
                "Device",
                /*"ClickType"/*,*/
                //"Period",
                //"AccountCurrencyCode",
                //"AccountDescriptiveName",
                //"AccountTimeZoneId",
                //"Amount",
                //"BiddingStrategy",
                //"BudgetId",
                //"CampaignName",
                //"CampaignStatus",
                //"ConversionOptimizerBidType",
                //"ConversionRateManyPerClick",
                "ConversionsManyPerClick",
                //"CostPerConversion",
                //"CostPerConversionManyPerClick",
                //"CustomerDescriptiveName",
                //"DerivedDailyBudget",
                //"EnhancedCpcEnabled",
                "ExternalCustomerId",
                //"Name",
                //"PrimaryCompanyName",
                //"Quarter",
                //"Slot",
                //"ValuePerConversion",
                //"ValuePerConversionManyPerClick",
                "ViewThroughConversions"
        ));

        DateRange dateRange = new DateRange();
        dateRange.setMax(date.replaceAll("-",""));
        dateRange.setMin(date.replaceAll("-",""));
        selector.setDateRange(dateRange);

        // Location to download report to.
        String reportFile = locationFile + File.separatorChar + "CampaignReport-" + date + ".xml";

        // Create predicates.
        /*com.google.api.ads.adwords.lib.jaxb.v201302.Predicate campaignIdPredicate =
                new com.google.api.ads.adwords.lib.jaxb.v201302.Predicate();
        campaignIdPredicate.setField("CampaignId");
        campaignIdPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201302.PredicateOperator.IN);
        campaignIdPredicate.getValues().addAll(Lists.newArrayList(campaignId.toString()));  */


        //("CampaignId", com.google.api.ads.adwords.lib.jaxb.v201302.PredicateOperator.IN, new String[] {campaignId.toString()});
        // selector.getPredicates().addAll(Lists.newArrayList(campaignIdPredicate));


        // Create report definition.
        ReportDefinition reportDefinition = new ReportDefinition();
        reportDefinition.setReportName("Campaign performance report #" + date);
        reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.CUSTOM_DATE);
        reportDefinition.setReportType(ReportDefinitionReportType.CAMPAIGN_PERFORMANCE_REPORT);
        reportDefinition.setDownloadFormat(DownloadFormat.XML);
        // Enable to allow rows with zero impressions to show.
        reportDefinition.setIncludeZeroImpressions(false);
        reportDefinition.isIncludeZeroImpressions();
        reportDefinition.setSelector(selector);


        try {
            // Set the property api.adwords.reportDownloadTimeout or call
            // ReportDownloader.setReportDownloadTimeout to set a timeout (in milliseconds)
            // for CONNECT and READ in report downloads.

            ReportDownloadResponse response =
                    new ReportDownloader(session).downloadReport(reportDefinition);

            FileOutputStream fos = new FileOutputStream(new File(reportFile));
            Streams.copy(response.getInputStream(), fos);
            fos.close();
            System.out.println("Report successfully downloaded: " + reportFile);
        } catch (ReportDownloadResponseException e) {
            System.out.println("Report was not downloaded. " + e.toString());
        }


    }

    public void GetSpendForClients(String clientIds, String locationFile, String startDate, String endDate, Long waitBetweenRequests, boolean searchNetwork, boolean displayNetwork){

        try{


            Credential oAuth2Credential = new OfflineCredentials.Builder()
                    .forApi(OfflineCredentials.Api.ADWORDS)
                    .fromFile()
                    .build()
                    .generateCredential();


            String[] clientIdsArray = clientIds.split(";");

            ArrayList<Thread> threads = new ArrayList<Thread>();


            for (int i = 0; i < clientIdsArray.length; i++){

                AdWordsSession session = new AdWordsSession.Builder()
                        .fromFile()
                        .withOAuth2Credential(oAuth2Credential)
                        .build();
                session.setClientCustomerId(clientIdsArray[i]);

                GetAccountReport report = new GetAccountReport(session, locationFile, startDate, endDate, searchNetwork, displayNetwork);
                report.start();
                threads.add(report);
                Thread.sleep(waitBetweenRequests);

            }

            for(Thread thread : threads){

                try {
                    thread.join();

                } catch (InterruptedException e) {
                    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }

            }

        }catch (Exception e){
            e.printStackTrace();
        }


    }

    public void GetCampaignSpendForClients(String clientIds, String locationFile, String startDate, String endDate, Long waitBetweenRequests, boolean searchNetwork, boolean displayNetwork){
        try{


            Credential oAuth2Credential = new OfflineCredentials.Builder()
                    .forApi(OfflineCredentials.Api.ADWORDS)
                    .fromFile()
                    .build()
                    .generateCredential();




            String[] clientIdsArray = clientIds.split(";");


            for (int i = 0; i < clientIdsArray.length; i++){

                AdWordsSession session = new AdWordsSession.Builder()
                        .fromFile()
                        .withOAuth2Credential(oAuth2Credential)
                        .build();
                session.setClientCustomerId(clientIdsArray[i]);

                GetCampaignReport report = new GetCampaignReport(session, locationFile, startDate, endDate, searchNetwork, displayNetwork);
                report.start();
                Thread.sleep(waitBetweenRequests);

            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void GetSegmentedConversionsCampaign(String clientId, String locationFile, String startDate, String endDate) throws Exception{

        Credential oAuth2Credential = new OfflineCredentials.Builder()
                .forApi(OfflineCredentials.Api.ADWORDS)
                .fromFile()
                .build()
                .generateCredential();

        AdWordsSession session = new AdWordsSession.Builder()
                .fromFile()
                .withOAuth2Credential(oAuth2Credential)
                .build();

        session.setClientCustomerId(clientId);

        com.google.api.ads.adwords.lib.jaxb.v201406.Selector selector = new com.google.api.ads.adwords.lib.jaxb.v201406.Selector();
        selector.getFields().addAll(Lists.newArrayList(
                "CampaignId",
                "CampaignName",
                "Id",
                "Conversions",
                "ConversionTypeName",
                "ConversionsManyPerClick",
                "Device"

        ));



        DateRange dateRange = new DateRange();
        dateRange.setMax(endDate.replaceAll("-",""));
        dateRange.setMin(startDate.replaceAll("-",""));
        selector.setDateRange(dateRange);

        // Location to download report to.
        String reportFile = locationFile + File.separatorChar + "SegmentedConversionsCampaignReport-" + startDate + "_" + endDate + ".xml";

        // Create predicates.
        /*com.google.api.ads.adwords.lib.jaxb.v201302.Predicate campaignIdPredicate =
                new com.google.api.ads.adwords.lib.jaxb.v201302.Predicate();
        campaignIdPredicate.setField("CampaignId");
        campaignIdPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201302.PredicateOperator.IN);
        campaignIdPredicate.getValues().addAll(Lists.newArrayList(campaignId.toString()));  */
        com.google.api.ads.adwords.lib.jaxb.v201406.Predicate conversionPredicate =
                new com.google.api.ads.adwords.lib.jaxb.v201406.Predicate();
        conversionPredicate.setField("ConversionTypeName");
        conversionPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201406.PredicateOperator.IN);
        conversionPredicate.getValues().add("Lead");
        conversionPredicate.getValues().add("lead");
        conversionPredicate.getValues().add("LEAD");
        conversionPredicate.getValues().add("leads");
        conversionPredicate.getValues().add("Leads");
        conversionPredicate.getValues().add("Lead submissions");
        conversionPredicate.getValues().add("Lead Submissions");
        conversionPredicate.getValues().add("Naples Luxury Imports (Leads)");
        //conversionPredicate.getValues().addAll(Lists.newArrayList(campaignId.toString()));

        selector.getPredicates().add(conversionPredicate);
        //("CampaignId", com.google.api.ads.adwords.lib.jaxb.v201302.PredicateOperator.IN, new String[] {campaignId.toString()});
        // selector.getPredicates().addAll(Lists.newArrayList(campaignIdPredicate));


        // Create report definition.
        ReportDefinition reportDefinition = new ReportDefinition();
        reportDefinition.setReportName("Campaign performance report #" + startDate + "_" + endDate );
        reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.CUSTOM_DATE);
        reportDefinition.setReportType(ReportDefinitionReportType.CAMPAIGN_PERFORMANCE_REPORT);
        reportDefinition.setDownloadFormat(DownloadFormat.XML);
        // Enable to allow rows with zero impressions to show.
        reportDefinition.setIncludeZeroImpressions(false);
        reportDefinition.isIncludeZeroImpressions();
        reportDefinition.setSelector(selector);


        try {
            // Set the property api.adwords.reportDownloadTimeout or call
            // ReportDownloader.setReportDownloadTimeout to set a timeout (in milliseconds)
            // for CONNECT and READ in report downloads.

            ReportDownloadResponse response =
                    new ReportDownloader(session).downloadReport(reportDefinition);

            FileOutputStream fos = new FileOutputStream(new File(reportFile));
            Streams.copy(response.getInputStream(), fos);
            fos.close();
            System.out.println("Report successfully downloaded: " + reportFile);
        } catch (ReportDownloadResponseException e) {
            System.out.println("Report was not downloaded. " + e.toString());
        }


    }

    public void GetSegmentedConversionsReport(String clientId, String locationFile, String date) throws Exception{
        Credential oAuth2Credential = new OfflineCredentials.Builder()
                .forApi(OfflineCredentials.Api.ADWORDS)
                .fromFile()
                .build()
                .generateCredential();

        AdWordsSession session = new AdWordsSession.Builder()
                .fromFile()
                .withOAuth2Credential(oAuth2Credential)
                .build();

        session.setClientCustomerId(clientId);

        com.google.api.ads.adwords.lib.jaxb.v201406.Selector selector = new com.google.api.ads.adwords.lib.jaxb.v201406.Selector();
        selector.getFields().addAll(Lists.newArrayList(
                "CampaignId",
                "CampaignName",
                "Id",
                "Conversions",
                "ConversionTypeName",
                "ConversionsManyPerClick",
                "Device"

        ));



        DateRange dateRange = new DateRange();
        dateRange.setMax(date.replaceAll("-",""));
        dateRange.setMin(date.replaceAll("-",""));
        selector.setDateRange(dateRange);

        // Location to download report to.
        String reportFile = locationFile + File.separatorChar + "SegmentedConversionsCampaignReport-" + date + ".xml";

        // Create predicates.
        /*com.google.api.ads.adwords.lib.jaxb.v201302.Predicate campaignIdPredicate =
                new com.google.api.ads.adwords.lib.jaxb.v201302.Predicate();
        campaignIdPredicate.setField("CampaignId");
        campaignIdPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201302.PredicateOperator.IN);
        campaignIdPredicate.getValues().addAll(Lists.newArrayList(campaignId.toString()));  */
        com.google.api.ads.adwords.lib.jaxb.v201406.Predicate conversionPredicate =
                new com.google.api.ads.adwords.lib.jaxb.v201406.Predicate();
        conversionPredicate.setField("ConversionTypeName");
        conversionPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201406.PredicateOperator.IN);
        conversionPredicate.getValues().add("Lead");
        conversionPredicate.getValues().add("lead");
        conversionPredicate.getValues().add("LEAD");
        conversionPredicate.getValues().add("leads");
        conversionPredicate.getValues().add("Leads");
        conversionPredicate.getValues().add("Lead submissions");
        conversionPredicate.getValues().add("Lead Submissions");
        //conversionPredicate.getValues().addAll(Lists.newArrayList(campaignId.toString()));

        selector.getPredicates().add(conversionPredicate);
        //("CampaignId", com.google.api.ads.adwords.lib.jaxb.v201302.PredicateOperator.IN, new String[] {campaignId.toString()});
        // selector.getPredicates().addAll(Lists.newArrayList(campaignIdPredicate));


        // Create report definition.
        ReportDefinition reportDefinition = new ReportDefinition();
        reportDefinition.setReportName("Campaign performance report #" + date);
        reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.CUSTOM_DATE);
        reportDefinition.setReportType(ReportDefinitionReportType.CAMPAIGN_PERFORMANCE_REPORT);
        reportDefinition.setDownloadFormat(DownloadFormat.XML);
        // Enable to allow rows with zero impressions to show.
        reportDefinition.setIncludeZeroImpressions(false);
        reportDefinition.isIncludeZeroImpressions();
        reportDefinition.setSelector(selector);


        try {
            // Set the property api.adwords.reportDownloadTimeout or call
            // ReportDownloader.setReportDownloadTimeout to set a timeout (in milliseconds)
            // for CONNECT and READ in report downloads.

            ReportDownloadResponse response =
                    new ReportDownloader(session).downloadReport(reportDefinition);

            FileOutputStream fos = new FileOutputStream(new File(reportFile));
            Streams.copy(response.getInputStream(), fos);
            fos.close();
            System.out.println("Report successfully downloaded: " + reportFile);
        } catch (ReportDownloadResponseException e) {
            System.out.println("Report was not downloaded. " + e.toString());
        }
    }

    public void GetCallsReport(String clientId, String locationFile, String date) throws Exception{
        Credential oAuth2Credential = new OfflineCredentials.Builder()
                .forApi(OfflineCredentials.Api.ADWORDS)
                .fromFile()
                .build()
                .generateCredential();

        AdWordsSession session = new AdWordsSession.Builder()
                .fromFile()
                .withOAuth2Credential(oAuth2Credential)
                .build();

        session.setClientCustomerId(clientId);

        com.google.api.ads.adwords.lib.jaxb.v201406.Selector selector = new com.google.api.ads.adwords.lib.jaxb.v201406.Selector();

        selector.getFields().addAll(Lists.newArrayList(
                "AdGroupId",
                "AdvertiserPhoneNumber",
                "CallDuration",
                "CallEndTime",
                "CallStartTime",
                "CallStatus",
                "CallType",
                "CallerCountryCallingCode",
                "CallerNationalDesignatedCode",
                "CampaignId",
                "OfflineInteractionCost"
        ));

        DateRange dateRange = new DateRange();
        dateRange.setMax(date.replaceAll("-",""));
        dateRange.setMin(date.replaceAll("-",""));
        //selector.setDateRange(dateRange);

        // Location to download report to.
        String reportFile = locationFile + File.separatorChar + "CallMetrics-" + date + ".xml";

        // Create predicates.
        /*com.google.api.ads.adwords.lib.jaxb.v201302.Predicate campaignIdPredicate =
                new com.google.api.ads.adwords.lib.jaxb.v201302.Predicate();
        campaignIdPredicate.setField("AdGroupId");
        campaignIdPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201302.PredicateOperator.IN);
        campaignIdPredicate.getValues().addAll(Lists.newArrayList(adGroupId.toString())); */


        // Create report definition.
        ReportDefinition reportDefinition = new ReportDefinition();
        reportDefinition.setReportName("Call metrics call details report #" /*+ date*/);
        reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.ALL_TIME);
        reportDefinition.setReportType(ReportDefinitionReportType.CALL_METRICS_CALL_DETAILS_REPORT);
        reportDefinition.setDownloadFormat(DownloadFormat.XML);
        // Enable to allow rows with zero impressions to show.
        reportDefinition.setIncludeZeroImpressions(false);
        reportDefinition.isIncludeZeroImpressions();
        reportDefinition.setSelector(selector);


        try {
            // Set the property api.adwords.reportDownloadTimeout or call
            // ReportDownloader.setReportDownloadTimeout to set a timeout (in milliseconds)
            // for CONNECT and READ in report downloads.

            ReportDownloadResponse response =
                    new ReportDownloader(session).downloadReport(reportDefinition);

            FileOutputStream fos = new FileOutputStream(new File(reportFile));
            Streams.copy(response.getInputStream(), fos);
            fos.close();

            System.out.println("Report successfully downloaded: " + reportFile);
        } catch (ReportDownloadResponseException e) {
            System.out.println("Report was not downloaded. " + e.toString());
        }


    }

    public void GetAccountReport(String clientId, String locationFile, String date) throws Exception {

        Credential oAuth2Credential = new OfflineCredentials.Builder()
                .forApi(OfflineCredentials.Api.ADWORDS)
                .fromFile()
                .build()
                .generateCredential();

        AdWordsSession session = new AdWordsSession.Builder()
                .fromFile()
                .withOAuth2Credential(oAuth2Credential)
                .build();

        session.setClientCustomerId(clientId);

        com.google.api.ads.adwords.lib.jaxb.v201406.Selector selector = new com.google.api.ads.adwords.lib.jaxb.v201406.Selector();

        selector.getFields().addAll(Lists.newArrayList(
                "AccountCurrencyCode",
                "AccountDescriptiveName",
                "AccountTimeZoneId",
                //"AdNetworkType1",
                //"AdNetworkType2",
                "AverageCpc",
                "AverageCpm",
                "AveragePosition",
                "Clicks",
                //"ClickType",
                "ConversionRate",
                "ConversionRateManyPerClick",
                "Conversions",
                "ConversionsManyPerClick",
                "ConversionValue",
                "Cost",
                "CostPerConversion",
                "CostPerConversionManyPerClick",
                "Ctr",
                "CustomerDescriptiveName",
                //"Device",
                "ExternalCustomerId",
                "Impressions",
                "InvalidClickRate",
                "InvalidClicks",
                "PrimaryCompanyName",
                "ValuePerConversion",
                "ValuePerConversionManyPerClick",
                "ViewThroughConversions"
        ));

        DateRange dateRange = new DateRange();
        dateRange.setMax(date.replaceAll("-",""));
        dateRange.setMin(date.replaceAll("-",""));
        selector.setDateRange(dateRange);

        // Location to download report to.
        String reportFile = locationFile + File.separatorChar + "AccountReport-" + date + ".xml";

        // Create predicates.
        com.google.api.ads.adwords.lib.jaxb.v201406.Predicate campaignIdPredicate =
                new com.google.api.ads.adwords.lib.jaxb.v201406.Predicate();
        campaignIdPredicate.setField("ExternalCustomerId");
        campaignIdPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201406.PredicateOperator.IN);
        campaignIdPredicate.getValues().addAll(Lists.newArrayList(clientId));


        // Create report definition.
        ReportDefinition reportDefinition = new ReportDefinition();
        reportDefinition.setReportName("Account performance report #" + date);
        reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.CUSTOM_DATE);
        reportDefinition.setReportType(ReportDefinitionReportType.ACCOUNT_PERFORMANCE_REPORT);
        reportDefinition.setDownloadFormat(DownloadFormat.XML);
        // Enable to allow rows with zero impressions to show.
        reportDefinition.setIncludeZeroImpressions(false);
        reportDefinition.isIncludeZeroImpressions();
        reportDefinition.setSelector(selector);


        try {
            // Set the property api.adwords.reportDownloadTimeout or call
            // ReportDownloader.setReportDownloadTimeout to set a timeout (in milliseconds)
            // for CONNECT and READ in report downloads.

            ReportDownloadResponse response =
                    new ReportDownloader(session).downloadReport(reportDefinition);

            FileOutputStream fos = new FileOutputStream(new File(reportFile));
            Streams.copy(response.getInputStream(), fos);
            fos.close();
            System.out.println("Report successfully downloaded: " + reportFile);
        } catch (ReportDownloadResponseException e) {
            System.out.println("Report was not downloaded. " + e.toString());
        }

    }

    public void GetAdGroupReport(String clientId, String locationFile, String date) throws Exception {

        Credential oAuth2Credential = new OfflineCredentials.Builder()
                .forApi(OfflineCredentials.Api.ADWORDS)
                .fromFile()
                .build()
                .generateCredential();

        AdWordsSession session = new AdWordsSession.Builder()
                .fromFile()
                .withOAuth2Credential(oAuth2Credential)
                .build();

        session.setClientCustomerId(clientId);

        com.google.api.ads.adwords.lib.jaxb.v201406.Selector selector = new com.google.api.ads.adwords.lib.jaxb.v201406.Selector();

        selector.getFields().addAll(Lists.newArrayList(
                //"AccountCurrencyCode",
                //"AccountDescriptiveName",
                //"AccountTimeZoneId",
                "AdGroupId",
                //"AdGroupName",
                //"AdGroupStatus",
                //"AdNetworkType1",
                //"AdNetworkType2",
                //"AverageCpc",
                //"AverageCpm",
                "AveragePosition",
                "CampaignId",
                //"CampaignName",
                //"CampaignStatus",
                "Clicks",
                //"ClickType",
                //"ConversionOptimizerBidType",
                //"ConversionRate",
                //"ConversionRateManyPerClick",
                "Conversions",
                "ConversionsManyPerClick",
                //"ConversionValue",
                "Cost",
                //"CostPerConversion",
                //"CostPerConversionManyPerClick",
                //"Ctr",
                //"CustomerDescriptiveName",
                //"Device",
                //"EnhancedCpcEnabled",
                "ExternalCustomerId",
                "Id",
                "Impressions",
                //"KeywordContentMaxCpc",
                //"KeywordMaxCpc",
                //"MaxCpm",
                //"Name",
                //"PercentCpa",
                //"PrimaryCompanyName",
                //"ProxyKeywordMaxCpc",
                //"Status",
                //"TargetCpa",
                //"ValuePerConversion",
                //"ValuePerConversionManyPerClick",
                "ViewThroughConversions"
        ));

        DateRange dateRange = new DateRange();
        dateRange.setMax(date.replaceAll("-",""));
        dateRange.setMin(date.replaceAll("-",""));
        selector.setDateRange(dateRange);

        // Location to download report to.
        String reportFile = locationFile + File.separatorChar + "AdGroupReport-" + date + ".xml";

        // Create predicates.
        /*com.google.api.ads.adwords.lib.jaxb.v201302.Predicate campaignIdPredicate =
                new com.google.api.ads.adwords.lib.jaxb.v201302.Predicate();
        campaignIdPredicate.setField("AdGroupId");
        campaignIdPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201302.PredicateOperator.IN);
        campaignIdPredicate.getValues().addAll(Lists.newArrayList(adGroupId.toString())); */


        // Create report definition.
        ReportDefinition reportDefinition = new ReportDefinition();
        reportDefinition.setReportName("AdGroup performance report #" + date);
        reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.CUSTOM_DATE);
        reportDefinition.setReportType(ReportDefinitionReportType.ADGROUP_PERFORMANCE_REPORT);
        reportDefinition.setDownloadFormat(DownloadFormat.XML);
        // Enable to allow rows with zero impressions to show.
        reportDefinition.setIncludeZeroImpressions(false);
        reportDefinition.isIncludeZeroImpressions();
        reportDefinition.setSelector(selector);


        try {
            // Set the property api.adwords.reportDownloadTimeout or call
            // ReportDownloader.setReportDownloadTimeout to set a timeout (in milliseconds)
            // for CONNECT and READ in report downloads.

            ReportDownloadResponse response =
                    new ReportDownloader(session).downloadReport(reportDefinition);

            FileOutputStream fos = new FileOutputStream(new File(reportFile));
            Streams.copy(response.getInputStream(), fos);
            fos.close();
            System.out.println("Report successfully downloaded: " + reportFile);
        } catch (ReportDownloadResponseException e) {
            System.out.println("Report was not downloaded. " + e.toString());
        }


    }

    public void GetAdReport(String clientId, String locationFile, String date) throws Exception {

        Credential oAuth2Credential = new OfflineCredentials.Builder()
                .forApi(OfflineCredentials.Api.ADWORDS)
                .fromFile()
                .build()
                .generateCredential();

        AdWordsSession session = new AdWordsSession.Builder()
                .fromFile()
                .withOAuth2Credential(oAuth2Credential)
                .build();
        session.setClientCustomerId(clientId);

        session.setClientCustomerId(clientId);

        com.google.api.ads.adwords.lib.jaxb.v201406.Selector selector = new com.google.api.ads.adwords.lib.jaxb.v201406.Selector();

        selector.getFields().addAll(Lists.newArrayList(
                //"AccountCurrencyCode",
                //"AccountDescriptiveName",
                //"AccountTimeZoneId",
                "AdGroupId",
                //"AdGroupName",
                //"AdGroupStatus",
                //"AdNetworkType1",
                //"AdNetworkType2",
                //"AdType",
                //"AverageCpc",
                //"AverageCpm",
                "AveragePosition",
                "CampaignId",
                //"CampaignName",
                //"CampaignStatus",
                "Clicks",
                //"ClickType",
                //"ConversionRate",
                //"ConversionRateManyPerClick",
                "Conversions",
                "ConversionsManyPerClick",
                //"ConversionValue",
                "Cost",
                //"CostPerConversion",
                //"CostPerConversionManyPerClick",
                //"CreativeApprovalStatus",
                //"CreativeDestinationUrl",
                //"Ctr",
                //"CustomerDescriptiveName",
                //"Description1",
                //"Description2",
                "Device",
                //"DisplayUrl",
                "ExternalCustomerId",
                //"Headline",
                "Id",
                //"ImageCreativeName",
                "Impressions",
                //"IsNegative",
                //"KeywordId",
                //"PrimaryCompanyName",
                //"PromotionLine",
                //"Status",
                //"ValuePerConversion",
                //"ValuePerConversionManyPerClick",
                "ViewThroughConversions"

        ));

        DateRange dateRange = new DateRange();
        dateRange.setMax(date.replaceAll("-",""));
        dateRange.setMin(date.replaceAll("-",""));
        selector.setDateRange(dateRange);

        // Location to download report to.
        String reportFile = locationFile + File.separatorChar + "AdReport-" + date + ".xml";

        // Create predicates.
        /*Predicate campaignIdPredicate = new Predicate();
        campaignIdPredicate.setField("AdType");
        campaignIdPredicate.setOperator(PredicateOperator.EQUALS);
        campaignIdPredicate.getValues().addAll(Lists.newArrayList("Text ad"));*/


        // Create report definition.
        ReportDefinition reportDefinition = new ReportDefinition();
        reportDefinition.setReportName("Ad performance report #" + date);
        reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.CUSTOM_DATE);
        reportDefinition.setReportType(ReportDefinitionReportType.AD_PERFORMANCE_REPORT);
        reportDefinition.setDownloadFormat(DownloadFormat.XML);
        // Enable to allow rows with zero impressions to show.
        reportDefinition.setIncludeZeroImpressions(false);
        reportDefinition.isIncludeZeroImpressions();
        reportDefinition.setSelector(selector);


        try {
            // Set the property api.adwords.reportDownloadTimeout or call
            // ReportDownloader.setReportDownloadTimeout to set a timeout (in milliseconds)
            // for CONNECT and READ in report downloads.

            ReportDownloadResponse response =
                    new ReportDownloader(session).downloadReport(reportDefinition);

            FileOutputStream fos = new FileOutputStream(new File(reportFile));
            Streams.copy(response.getInputStream(), fos);
            fos.close();
            System.out.println("Report successfully downloaded: " + reportFile);
        } catch (ReportDownloadResponseException e) {
            System.out.println("Report was not downloaded. " + e.toString());
        }
    }

    public void GetKeywordReport(String clientId, String locationFile, String date) throws Exception {

        Credential oAuth2Credential = new OfflineCredentials.Builder()
                .forApi(OfflineCredentials.Api.ADWORDS)
                .fromFile()
                .build()
                .generateCredential();

        AdWordsSession session = new AdWordsSession.Builder()
                .fromFile()
                .withOAuth2Credential(oAuth2Credential)
                .build();
        session.setClientCustomerId(clientId);

        com.google.api.ads.adwords.lib.jaxb.v201406.Selector selector = new com.google.api.ads.adwords.lib.jaxb.v201406.Selector();

        selector.getFields().addAll(Lists.newArrayList(
                //"AccountCurrencyCode",
                //"AccountDescriptiveName",
                //"AccountTimeZoneId",
                "AdGroupId",
                //"AdGroupName",
                //"AdGroupStatus",
                //"AdNetworkType1",
                //"AdNetworkType2",
                //"ApprovalStatus",
                //"AverageCpc",
                //"AverageCpm",
                "AveragePosition",
                //"BottomPosition",
                "CampaignId",
                //"CampaignName",
                //"CampaignStatus",
                "Clicks",
                //"ClickType",
                //"ConversionRate",
                //"ConversionRateManyPerClick",
                "Conversions",
                "ConversionsManyPerClick",
                //"ConversionValue",
                "Cost",
                //"CostPerConversion",
                //"CostPerConversionManyPerClick",
                //"CpcBidSource",
                //"CriteriaDestinationUrl",
                //"Ctr",
                //"CustomerDescriptiveName",
                //"DestinationUrl",
                //"Device",
                "ExternalCustomerId",
                //"FirstPageCpc",
                "Id",
                "Impressions",
                //"IsNegative",
                //"KeywordMatchType",
                //"KeywordText",
                //"MaxCpc",
                //"MaxCpm",
                //"OriginalMaxCpc",
                //"PercentCpa",
                //"PlacementUrl",
                //"PreferredPosition",
                //"PrimaryCompanyName",
                //"QualityScore",
                //"Status",
                //"ValuePerConversion",
                //"ValuePerConversionManyPerClick",
                "ViewThroughConversions"

        ));

        DateRange dateRange = new DateRange();
        dateRange.setMax(date.replaceAll("-",""));
        dateRange.setMin(date.replaceAll("-",""));
        selector.setDateRange(dateRange);

        // Location to download report to.
        String reportFile = locationFile + File.separatorChar + "KeywordReport-" + date + ".xml";

        // Create predicates.
        /*com.google.api.ads.adwords.lib.jaxb.v201302.Predicate campaignIdPredicate =
                new com.google.api.ads.adwords.lib.jaxb.v201302.Predicate();
        campaignIdPredicate.setField("AdGroupId");
        campaignIdPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201302.PredicateOperator.IN);
        campaignIdPredicate.getValues().addAll(Lists.newArrayList(adGroupId.toString()));*/


        // Create report definition.
        ReportDefinition reportDefinition = new ReportDefinition();
        reportDefinition.setReportName("Keywords performance report #" + date);
        reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.CUSTOM_DATE);
        reportDefinition.setReportType(ReportDefinitionReportType.KEYWORDS_PERFORMANCE_REPORT);
        reportDefinition.setDownloadFormat(DownloadFormat.XML);
        // Enable to allow rows with zero impressions to show.
        reportDefinition.setIncludeZeroImpressions(false);
        reportDefinition.isIncludeZeroImpressions();
        reportDefinition.setSelector(selector);


        try {
            // Set the property api.adwords.reportDownloadTimeout or call
            // ReportDownloader.setReportDownloadTimeout to set a timeout (in milliseconds)
            // for CONNECT and READ in report downloads.

            ReportDownloadResponse response =
                    new ReportDownloader(session).downloadReport(reportDefinition);

            FileOutputStream fos = new FileOutputStream(new File(reportFile));
            Streams.copy(response.getInputStream(), fos);
            fos.close();
            System.out.println("Report successfully downloaded: " + reportFile);
        } catch (ReportDownloadResponseException e) {
            System.out.println("Report was not downloaded. " + e.toString());
        }
    }

    public void GetKeywordReportRange(String clientId, String locationFile, String startDate, String endDate) throws Exception {

        Credential oAuth2Credential = new OfflineCredentials.Builder()
                .forApi(OfflineCredentials.Api.ADWORDS)
                .fromFile()
                .build()
                .generateCredential();

        AdWordsSession session = new AdWordsSession.Builder()
                .fromFile()
                .withOAuth2Credential(oAuth2Credential)
                .build();
        session.setClientCustomerId(clientId);

        com.google.api.ads.adwords.lib.jaxb.v201406.Selector selector = new com.google.api.ads.adwords.lib.jaxb.v201406.Selector();

        selector.getFields().addAll(Lists.newArrayList(
                "AdGroupId",
                "AveragePosition",
                "CampaignId",
                "Clicks",
                "Conversions",
                "ConversionsManyPerClick",
                "Cost",
                "ExternalCustomerId",
                "Id",
                "KeywordText",
                "Impressions",
                "ViewThroughConversions"

        ));

        DateRange dateRange = new DateRange();
        dateRange.setMax(endDate.replaceAll("-",""));
        dateRange.setMin(startDate.replaceAll("-",""));
        selector.setDateRange(dateRange);

        // Location to download report to.
        String reportFile = locationFile + File.separatorChar + "KeywordReport-" + clientId + "_" + startDate + "_" + endDate + ".xml";


        // Create report definition.
        ReportDefinition reportDefinition = new ReportDefinition();
        reportDefinition.setReportName("Keywords performance report #" + startDate + "_" + endDate);
        reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.CUSTOM_DATE);
        reportDefinition.setReportType(ReportDefinitionReportType.KEYWORDS_PERFORMANCE_REPORT);
        reportDefinition.setDownloadFormat(DownloadFormat.XML);
        // Enable to allow rows with zero impressions to show.
        reportDefinition.setIncludeZeroImpressions(false);
        reportDefinition.isIncludeZeroImpressions();
        reportDefinition.setSelector(selector);


        try {
            // Set the property api.adwords.reportDownloadTimeout or call
            // ReportDownloader.setReportDownloadTimeout to set a timeout (in milliseconds)
            // for CONNECT and READ in report downloads.

            ReportDownloadResponse response =
                    new ReportDownloader(session).downloadReport(reportDefinition);

            FileOutputStream fos = new FileOutputStream(new File(reportFile));
            Streams.copy(response.getInputStream(), fos);
            fos.close();
            System.out.println("Report successfully downloaded: " + reportFile);
        } catch (ReportDownloadResponseException e) {
            System.out.println("Report was not downloaded. " + e.toString());
        }
    }

    public void GetTopKeywordsReportForClients(String clientIds, String locationFile, String startDate, String endDate, Long waitBetweenRequests){
        String[] clientIdsArray = clientIds.split(";");

        ArrayList<Thread> threads = new ArrayList<Thread>();

        for(String clientId : clientIdsArray){

            GetKeywordReportRangeThread keywordReport = new GetKeywordReportRangeThread(Long.parseLong(clientId), locationFile, startDate, endDate);
            keywordReport.start();
            threads.add(keywordReport);

            try {
                Thread.sleep(waitBetweenRequests);
            } catch (InterruptedException e) {
                //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }


        }


        for(Thread thread : threads){

            try {
                thread.join();

            } catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }

        }

    }

    public void GetCriterionReport(String clientId, String locationFile, String date) throws Exception {

        Credential oAuth2Credential = new OfflineCredentials.Builder()
                .forApi(OfflineCredentials.Api.ADWORDS)
                .fromFile()
                .build()
                .generateCredential();

        AdWordsSession session = new AdWordsSession.Builder()
                .fromFile()
                .withOAuth2Credential(oAuth2Credential)
                .build();

        session.setClientCustomerId(clientId);

        com.google.api.ads.adwords.lib.jaxb.v201406.Selector selector = new com.google.api.ads.adwords.lib.jaxb.v201406.Selector();

        selector.getFields().addAll(Lists.newArrayList(
                "AdGroupId",
                "AdGroupName",
                "AdGroupStatus",
                //"AdNetworkType1",
                //"AdNetworkType2",
                "AverageCpc",
                "AverageCpm",
                "AveragePosition",
                //"BottomPosition",
                "CampaignId",
                "CampaignName",
                "CampaignStatus",
                "Clicks",
                //"ClickType",
                "ConversionRate",
                "ConversionRateManyPerClick",
                "Conversions",
                "ConversionsManyPerClick",
                "ConversionValue",
                "Cost",
                "CostPerConversion",
                "CostPerConversionManyPerClick",
                "CpcBidSource",
                "CriteriaDestinationUrl",
                "Ctr",
                "CustomerDescriptiveName",
                "DestinationUrl",
                //"Device",
                "ExternalCustomerId",
                "FirstPageCpc",
                "Id",
                "Impressions",
                "IsNegative",
                "KeywordMatchType",
                "KeywordText",
                "MaxCpc",
                "MaxCpm",
                "OriginalMaxCpc",
                "PercentCpa",
                //"PlacementUrl",
                //"PreferredPosition",
                "PrimaryCompanyName",
                "QualityScore",
                "Status",
                "ValuePerConversion",
                "ValuePerConversionManyPerClick",
                "ViewThroughConversions"

        ));

        DateRange dateRange = new DateRange();
        dateRange.setMax(date.replaceAll("-",""));
        dateRange.setMin(date.replaceAll("-",""));
        selector.setDateRange(dateRange);

        // Location to download report to.
        String reportFile = locationFile + File.separatorChar + "KeywordReport-" + date + ".xml";

        // Create predicates.
        /*com.google.api.ads.adwords.lib.jaxb.v201302.Predicate campaignIdPredicate =
                new com.google.api.ads.adwords.lib.jaxb.v201302.Predicate();
        campaignIdPredicate.setField("AdGroupId");
        campaignIdPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201302.PredicateOperator.IN);
        campaignIdPredicate.getValues().addAll(Lists.newArrayList(adGroupId.toString()));*/


        // Create report definition.
        ReportDefinition reportDefinition = new ReportDefinition();
        reportDefinition.setReportName("Placements performance report #" + date);
        reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.CUSTOM_DATE);
        reportDefinition.setReportType(ReportDefinitionReportType.PLACEMENT_PERFORMANCE_REPORT);
        reportDefinition.setDownloadFormat(DownloadFormat.XML);
        // Enable to allow rows with zero impressions to show.
        reportDefinition.setIncludeZeroImpressions(false);
        reportDefinition.isIncludeZeroImpressions();
        reportDefinition.setSelector(selector);


        try {
            // Set the property api.adwords.reportDownloadTimeout or call
            // ReportDownloader.setReportDownloadTimeout to set a timeout (in milliseconds)
            // for CONNECT and READ in report downloads.

            ReportDownloadResponse response =
                    new ReportDownloader(session).downloadReport(reportDefinition);

            FileOutputStream fos = new FileOutputStream(new File(reportFile));
            Streams.copy(response.getInputStream(), fos);
            fos.close();
            System.out.println("Report successfully downloaded: " + reportFile);
        } catch (ReportDownloadResponseException e) {
            System.out.println("Report was not downloaded. " + e.toString());
        }
    }

    public void GetAdExtensionReport(String clientId, String locationFile, String date) throws Exception {

        Credential oAuth2Credential = new OfflineCredentials.Builder()
                .forApi(OfflineCredentials.Api.ADWORDS)
                .fromFile()
                .build()
                .generateCredential();

        AdWordsSession session = new AdWordsSession.Builder()
                .fromFile()
                .withOAuth2Credential(oAuth2Credential)
                .build();

        session.setClientCustomerId(clientId);

        com.google.api.ads.adwords.lib.jaxb.v201406.Selector selector = new com.google.api.ads.adwords.lib.jaxb.v201406.Selector();

        selector.getFields().addAll(Lists.newArrayList(
                "AdExtensionId",
                "AdExtensionType",
                //"AdNetworkType1",
                //"AdNetworkType2",
                "ApprovalStatus",
                "AverageCpc",
                "AverageCpm",
                "AveragePosition",
                "CampaignId",
                "Clicks",
                //"ClickType",
                "ConversionRate",
                "ConversionRateManyPerClick",
                "Conversions",
                "ConversionsManyPerClick",
                "ConversionValue",
                "Cost",
                "CostPerConversion",
                "CostPerConversionManyPerClick",
                "Ctr",
                //"Device",
                "Impressions",
                "LocationExtensionSource",
                "Status",
                "ValuePerConversion"

        ));


        DateRange dateRange = new DateRange();
        dateRange.setMax(date.replaceAll("-",""));
        dateRange.setMin(date.replaceAll("-",""));
        selector.setDateRange(dateRange);

        // Location to download report to.
        String reportFile = locationFile + File.separatorChar + "AdExtensionReport-" + date + ".xml";

        // Create predicates.
        /*com.google.api.ads.adwords.lib.jaxb.v201302.Predicate campaignIdPredicate =
                new com.google.api.ads.adwords.lib.jaxb.v201302.Predicate();
        campaignIdPredicate.setField("AdGroupId");
        campaignIdPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201302.PredicateOperator.IN);
        campaignIdPredicate.getValues().addAll(Lists.newArrayList(adGroupId.toString()));*/


        // Create report definition.
        ReportDefinition reportDefinition = new ReportDefinition();
        reportDefinition.setReportName("AdExtensions performance report #" + date);
        reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.CUSTOM_DATE);
        reportDefinition.setReportType(ReportDefinitionReportType.AD_EXTENSIONS_PERFORMANCE_REPORT);
        reportDefinition.setDownloadFormat(DownloadFormat.XML);
        // Enable to allow rows with zero impressions to show.
        reportDefinition.setIncludeZeroImpressions(false);
        reportDefinition.isIncludeZeroImpressions();
        reportDefinition.setSelector(selector);


        try {
            // Set the property api.adwords.reportDownloadTimeout or call
            // ReportDownloader.setReportDownloadTimeout to set a timeout (in milliseconds)
            // for CONNECT and READ in report downloads.

            ReportDownloadResponse response =
                    new ReportDownloader(session).downloadReport(reportDefinition);

            FileOutputStream fos = new FileOutputStream(new File(reportFile));
            Streams.copy(response.getInputStream(), fos);
            fos.close();
            System.out.println("Report successfully downloaded: " + reportFile);
        } catch (ReportDownloadResponseException e) {
            System.out.println("Report was not downloaded. " + e.toString());
        }

    }

    public void GetCampaignKeywordsReport(String clientId, String locationFile, String date) throws Exception {

        Credential oAuth2Credential = new OfflineCredentials.Builder()
                .forApi(OfflineCredentials.Api.ADWORDS)
                .fromFile()
                .build()
                .generateCredential();

        AdWordsSession session = new AdWordsSession.Builder()
                .fromFile()
                .withOAuth2Credential(oAuth2Credential)
                .build();

        session.setClientCustomerId(clientId);

        com.google.api.ads.adwords.lib.jaxb.v201406.Selector selector = new com.google.api.ads.adwords.lib.jaxb.v201406.Selector();

        selector.getFields().addAll(Lists.newArrayList(
                "UserListId",
                "CampaignId",
                "Id",
                "IsNegative",
                "KeywordMatchType",
                "KeywordText",
                "PlacementUrl"

        ));

        DateRange dateRange = new DateRange();
        dateRange.setMax(date.replaceAll("-",""));
        dateRange.setMin(date.replaceAll("-",""));
        selector.setDateRange(dateRange);

        // Location to download report to.
        String reportFile = locationFile + File.separatorChar + "CampaignKeywordReport-" + date + ".xml";

        // Create predicates.
        /*com.google.api.ads.adwords.lib.jaxb.v201302.Predicate campaignIdPredicate =
                new com.google.api.ads.adwords.lib.jaxb.v201302.Predicate();
        campaignIdPredicate.setField("CampaignId");
        campaignIdPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201302.PredicateOperator.IN);
        campaignIdPredicate.getValues().addAll(Lists.newArrayList(campaignId.toString())); */


        // Create report definition.
        ReportDefinition reportDefinition = new ReportDefinition();
        reportDefinition.setReportName("Campaign Keywords performance report #" + date);
        reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.CUSTOM_DATE);
        reportDefinition.setReportType(ReportDefinitionReportType.CAMPAIGN_NEGATIVE_KEYWORDS_PERFORMANCE_REPORT);
        reportDefinition.setDownloadFormat(DownloadFormat.XML);
        // Enable to allow rows with zero impressions to show.
        reportDefinition.setIncludeZeroImpressions(false);
        reportDefinition.isIncludeZeroImpressions();
        reportDefinition.setSelector(selector);


        try {
            // Set the property api.adwords.reportDownloadTimeout or call
            // ReportDownloader.setReportDownloadTimeout to set a timeout (in milliseconds)
            // for CONNECT and READ in report downloads.

            ReportDownloadResponse response =
                    new ReportDownloader(session).downloadReport(reportDefinition);

            FileOutputStream fos = new FileOutputStream(new File(reportFile));
            Streams.copy(response.getInputStream(), fos);
            fos.close();
            System.out.println("Report successfully downloaded: " + reportFile);
        } catch (ReportDownloadResponseException e) {
            System.out.println("Report was not downloaded. " + e.toString());
        }


    }
}

class GetAccountReport extends Thread{

    private AdWordsSession session;
    private String locationFile;
    private String startDate;
    private String endDate;
    private boolean searchNetwork;
    private boolean displayNetwork;

    GetAccountReport(AdWordsSession session, String locationFile, String startDate, String endDate, boolean searchNetwork, boolean displayNetwork) {
        this.session = session;
        this.locationFile = locationFile;
        this.startDate = startDate;
        this.endDate = endDate;
        this.searchNetwork = searchNetwork;
        this.displayNetwork = displayNetwork;
    }


    public void run(){

        String[] selectorArray = new String[]{"ExternalCustomerId", "Cost"};

        if (!(searchNetwork && displayNetwork)){

            if (searchNetwork || displayNetwork)
                selectorArray = new String[]{"ExternalCustomerId", "Cost", "AdNetworkType1"};

        }


        if (searchNetwork && displayNetwork){
            selectorArray = new String[]{"ExternalCustomerId", "Cost", "AdNetworkType1"};
        }

        com.google.api.ads.adwords.lib.jaxb.v201406.Selector selector = new com.google.api.ads.adwords.lib.jaxb.v201406.Selector();

        selector.getFields().addAll(Lists.newArrayList(selectorArray));

        DateRange dateRange = new DateRange();
        dateRange.setMax(endDate.replaceAll("-",""));
        dateRange.setMin(startDate.replaceAll("-",""));
        selector.setDateRange(dateRange);

        // Location to download report to.
        String reportFile = locationFile + File.separatorChar + "SpendForClientReport-" + session.getClientCustomerId() + "_" + startDate + "_" + endDate + ".xml";

        // Create predicates.
        com.google.api.ads.adwords.lib.jaxb.v201406.Predicate campaignIdPredicate =
                new com.google.api.ads.adwords.lib.jaxb.v201406.Predicate();
        campaignIdPredicate.setField("AccountId");
        campaignIdPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201406.PredicateOperator.IN);
        campaignIdPredicate.getValues().addAll(Lists.newArrayList(session.getClientCustomerId()));

        com.google.api.ads.adwords.lib.jaxb.v201406.Predicate networkPredicate =
                new com.google.api.ads.adwords.lib.jaxb.v201406.Predicate();
        networkPredicate.setField("AdNetworkType1");
        networkPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201406.PredicateOperator.EQUALS);


        if (searchNetwork){
            networkPredicate.getValues().addAll(Lists.newArrayList("SEARCH"));
            selector.getPredicates().add(networkPredicate);
        }
        if (displayNetwork){
            networkPredicate.getValues().addAll(Lists.newArrayList("CONTENT"));
            selector.getPredicates().add(networkPredicate);
        }
        if (displayNetwork && searchNetwork){
            networkPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201406.PredicateOperator.IN);
            networkPredicate.getValues().addAll(Lists.newArrayList("SEARCH", "CONTENT"));
            selector.getPredicates().add(networkPredicate);
        }


        // Create report definition.
        ReportDefinition reportDefinition = new ReportDefinition();
        reportDefinition.setReportName("Account performance report #" + startDate + "_" + endDate);
        reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.CUSTOM_DATE);
        reportDefinition.setReportType(ReportDefinitionReportType.ACCOUNT_PERFORMANCE_REPORT);
        reportDefinition.setDownloadFormat(DownloadFormat.XML);
        // Enable to allow rows with zero impressions to show.
        reportDefinition.setIncludeZeroImpressions(false);
        reportDefinition.isIncludeZeroImpressions();
        reportDefinition.setSelector(selector);


        try {
            // Set the property api.adwords.reportDownloadTimeout or call
            // ReportDownloader.setReportDownloadTimeout to set a timeout (in milliseconds)
            // for CONNECT and READ in report downloads.

            ReportDownloadResponse response =
                    new ReportDownloader(session).downloadReport(reportDefinition);

            FileOutputStream fos = new FileOutputStream(new File(reportFile));
            Streams.copy(response.getInputStream(), fos);
            fos.close();
            System.out.println("Report successfully downloaded: " + reportFile);
        } catch (ReportDownloadResponseException e) {
            System.out.println("Report was not downloaded. " + e.toString());
        } catch (FileNotFoundException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            System.out.println("Report was not downloaded. " + e.toString());
        } catch (ReportException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            System.out.println("Report was not downloaded. " + e.toString());
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            System.out.println("Report was not downloaded. " + e.toString());
        }


    }
}

class GetCampaignReport extends Thread{

    private AdWordsSession session;
    private String locationFile;
    private String startDate;
    private String endDate;
    private boolean searchNetwork;
    private boolean displayNetwork;

    GetCampaignReport(AdWordsSession session, String locationFile, String startDate, String endDate, boolean searchNetwork, boolean displayNetwork) {
        this.session = session;
        this.locationFile = locationFile;
        this.startDate = startDate;
        this.endDate = endDate;
        this.searchNetwork = searchNetwork;
        this.displayNetwork = displayNetwork;
    }

    public void run(){

        String[] selectorArray = new String[]{"CampaignId","Cost", "ExternalCustomerId"};

        if (!(searchNetwork && displayNetwork)){

            if (searchNetwork || displayNetwork)
                selectorArray = new String[]{"CampaignId","Cost", "ExternalCustomerId", "AdNetworkType1"};

        }

        com.google.api.ads.adwords.lib.jaxb.v201406.Selector selector = new com.google.api.ads.adwords.lib.jaxb.v201406.Selector();
        selector.getFields().addAll(Lists.newArrayList(selectorArray));



        DateRange dateRange = new DateRange();
        dateRange.setMax(endDate.replaceAll("-",""));
        dateRange.setMin(startDate.replaceAll("-",""));
        selector.setDateRange(dateRange);

        // Create predicates.
        com.google.api.ads.adwords.lib.jaxb.v201406.Predicate campaignIdPredicate =
                new com.google.api.ads.adwords.lib.jaxb.v201406.Predicate();
        campaignIdPredicate.setField("ExternalCustomerId");
        campaignIdPredicate.setOperator(com.google.api.ads.adwords.lib.jaxb.v201406.PredicateOperator.IN);
        campaignIdPredicate.getValues().addAll(Lists.newArrayList(session.getClientCustomerId()));


        // Location to download report to.
        String reportFile = locationFile + File.separatorChar + "CampaignSpendForClientReport-" + session.getClientCustomerId() + "_" + startDate + "_" + endDate + ".xml";

        // Create report definition.
        ReportDefinition reportDefinition = new ReportDefinition();
        reportDefinition.setReportName("Campaign spend report #" + startDate + "_" + endDate);
        reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.CUSTOM_DATE);
        reportDefinition.setReportType(ReportDefinitionReportType.CAMPAIGN_PERFORMANCE_REPORT);
        reportDefinition.setDownloadFormat(DownloadFormat.XML);
        // Enable to allow rows with zero impressions to show.
        reportDefinition.setIncludeZeroImpressions(false);
        reportDefinition.isIncludeZeroImpressions();
        reportDefinition.setSelector(selector);


        try {
            // Set the property api.adwords.reportDownloadTimeout or call
            // ReportDownloader.setReportDownloadTimeout to set a timeout (in milliseconds)
            // for CONNECT and READ in report downloads.

            ReportDownloadResponse response =
                    new ReportDownloader(session).downloadReport(reportDefinition);

            FileOutputStream fos = new FileOutputStream(new File(reportFile));
            Streams.copy(response.getInputStream(), fos);
            fos.close();
            System.out.println("Report successfully downloaded: " + reportFile);
        } catch (ReportDownloadResponseException e) {
            System.out.println("Report was not downloaded. " + e.toString());
        } catch (FileNotFoundException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (ReportException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }


    }


}

class GetAllReports extends Thread{

    private Long clientId;
    private String locationFile;
    private String date;

    private final static Logger log = Logger.getLogger(GetAllReports.class);

    GetAllReports(Long clientId, String locationFile, String date) {
        this.clientId = clientId;
        this.locationFile = locationFile;
        this.date = date;
    }

    public void run(){

        ReportManager rm = new ReportManager();
        try{
            //System.out.println(locationFile + File.separator + clientId + "-" + date);

            //Thread.sleep(2000L);

            GetCampaignReportThread campaignReport = new GetCampaignReportThread(clientId, locationFile, date);
            campaignReport.start();
            /*GetAccountReportThread accountReport = new GetAccountReportThread(clientId, locationFile, date);
            accountReport.start(); */
            GetAdGroupReportThread adGroupReport = new GetAdGroupReportThread(clientId, locationFile, date);
            adGroupReport.start();
            GetAdReportThread adReport = new GetAdReportThread(clientId, locationFile, date);
            adReport.start();
            /*GetAdExtensionReportThread adExtensionReport = new GetAdExtensionReportThread(clientId, locationFile, date);
            adExtensionReport.start();*/
            GetKeywordReportThread keywordReport = new GetKeywordReportThread(clientId, locationFile, date);
            keywordReport.start();


        }catch (Exception e){
            log.error("Error in Get All Reports for client " + clientId + " in date " + date);

            StringWriter errors = new StringWriter();
            e.printStackTrace(new PrintWriter(errors));
            log.error(errors.toString());
        }




    }
}

class GetCampaignReportThread extends Thread{


    private final static Logger log = Logger.getLogger(GetCampaignReportThread.class);

    private Long clientId;
    private String locationFile;
    private String date;


    GetCampaignReportThread(Long clientId, String locationFile, String date) {
        this.clientId = clientId;
        this.locationFile = locationFile;
        this.date = date;
    }

    public void run(){
        ReportManager rm = new ReportManager();

        int maxRetries = 10;
        Long waitBetweenRetries = 3000L;

        try {
            HashMap<String, String> props = Properties.getEOProperties();

            maxRetries = Integer.parseInt(props.get("retries"));
            waitBetweenRetries = Long.parseLong(props.get("waitBetweenRetries"));
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }



        int retries = 0;
        boolean finished = false;

        while (retries < maxRetries && !finished){

            try {
                rm.GetCampaignReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);


                GetAdGroupReportThread adGroupReport = new GetAdGroupReportThread(clientId, locationFile, date);
                adGroupReport.start();


                GetAdReportThread adReport = new GetAdReportThread(clientId, locationFile, date);
                adReport.start();

                GetKeywordReportThread keywordReport = new GetKeywordReportThread(clientId, locationFile, date);
                keywordReport.start();

                GetCallReportThread callReport = new GetCallReportThread(clientId, locationFile, date);
                callReport.start();

                GetSegmentedConversionsReportThread segmentedReport = new GetSegmentedConversionsReportThread(clientId, locationFile, date);
                segmentedReport.start();


                adGroupReport.join();
                adReport.join();
                keywordReport.join();
                callReport.join();
                segmentedReport.join();


                finished = true;


            } catch (Exception e) {
                //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                retries++;
                log.error("Error in Get Campaign Report for client " + clientId + " in date " + date + ", Retry: " + retries);
                StringWriter errors = new StringWriter();
                e.printStackTrace(new PrintWriter(errors));
                log.error(errors.toString());
                try {
                    this.sleep(/*retries*/waitBetweenRetries);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
            }
        }
    }
}

class GetAdGroupReportThread extends Thread{

    private Long clientId;
    private String locationFile;
    private String date;
    private final static Logger log = Logger.getLogger(GetAdGroupReportThread.class);

    GetAdGroupReportThread(Long clientId, String locationFile, String date) {
        this.clientId = clientId;
        this.locationFile = locationFile;
        this.date = date;
    }

    public void run(){
        ReportManager rm = new ReportManager();

        int maxRetries = 10;
        Long waitBetweenRetries = 3000L;

        try {
            HashMap<String, String> props = Properties.getEOProperties();

            maxRetries = Integer.parseInt(props.get("retries"));
            waitBetweenRetries = Long.parseLong(props.get("waitBetweenRetries"));
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

        int retries = 0;
        boolean finished = false;

        while (retries < maxRetries && !finished){

            try {
                rm.GetAdGroupReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                finished = true;
               /* GetAdReportThread adReport = new GetAdReportThread(clientId, locationFile, date);
                adReport.start();
                adReport.join();  */
            } catch (Exception e) {
                retries++;
                log.error("Error in Get AdGroup Report for client " + clientId + " in date " + date + ", Retry: " + retries);
                StringWriter errors = new StringWriter();
                e.printStackTrace(new PrintWriter(errors));
                log.error(errors.toString());
                try {
                    this.sleep(retries*waitBetweenRetries);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
            }
        }
    }
}

class GetAccountReportThread extends Thread{

    private Long clientId;
    private String locationFile;
    private String date;
    private final static Logger log = Logger.getLogger(GetAccountReportThread.class);

    GetAccountReportThread(Long clientId, String locationFile, String date) {
        this.clientId = clientId;
        this.locationFile = locationFile;
        this.date = date;
    }

    public void run(){
        ReportManager rm = new ReportManager();

        int maxRetries = 10;
        Long waitBetweenRetries = 3000L;

        try {
            HashMap<String, String> props = Properties.getEOProperties();

            maxRetries = Integer.parseInt(props.get("retries"));
            waitBetweenRetries = Long.parseLong(props.get("waitBetweenRetries"));
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

        int retries = 0;
        boolean finished = false;

        while (retries < maxRetries && !finished){

            try {
                rm.GetAccountReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                finished = true;



            } catch (Exception e) {
                retries++;
                log.error("Error in Get Account Report for client " + clientId + " in date " + date + ", Retry: " + retries);


                StringWriter errors = new StringWriter();
                e.printStackTrace(new PrintWriter(errors));
                log.error(errors.toString());
                try {
                    this.sleep(retries*waitBetweenRetries);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
            }
        }
    }
}

class GetAdReportThread extends Thread{

    private Long clientId;
    private String locationFile;
    private String date;
    private final static Logger log = Logger.getLogger(GetAdReportThread.class);

    GetAdReportThread(Long clientId, String locationFile, String date) {
        this.clientId = clientId;
        this.locationFile = locationFile;
        this.date = date;
    }

    public void run(){
        ReportManager rm = new ReportManager();

        int maxRetries = 10;
        Long waitBetweenRetries = 3000L;

        try {
            HashMap<String, String> props = Properties.getEOProperties();

            maxRetries = Integer.parseInt(props.get("retries"));
            waitBetweenRetries = Long.parseLong(props.get("waitBetweenRetries"));
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

        int retries = 0;
        boolean finished = false;

        while (retries < maxRetries && !finished){

            try {
                rm.GetAdReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                finished = true;

                /*GetKeywordReportThread keywordReport = new GetKeywordReportThread(clientId, locationFile, date);
                keywordReport.start();
                keywordReport.join(); */
            } catch (Exception e) {
                retries++;
                log.error("Error in Get Ad Report for client " + clientId + " in date " + date + ", Retry: " + retries);

                StringWriter errors = new StringWriter();
                e.printStackTrace(new PrintWriter(errors));
                log.error(errors.toString());
                try {
                    this.sleep(retries*waitBetweenRetries);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
            }
        }
    }
}

class GetAdExtensionReportThread extends Thread{

    private Long clientId;
    private String locationFile;
    private String date;
    private final static Logger log = Logger.getLogger(GetAdExtensionReportThread.class);

    GetAdExtensionReportThread(Long clientId, String locationFile, String date) {
        this.clientId = clientId;
        this.locationFile = locationFile;
        this.date = date;
    }

    public void run(){
        ReportManager rm = new ReportManager();

        int maxRetries = 10;
        Long waitBetweenRetries = 3000L;

        try {
            HashMap<String, String> props = Properties.getEOProperties();

            maxRetries = Integer.parseInt(props.get("retries"));
            waitBetweenRetries = Long.parseLong(props.get("waitBetweenRetries"));
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

        int retries = 0;
        boolean finished = false;

        while (retries < maxRetries && !finished){
            try {
                rm.GetAdExtensionReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                finished = true;
            } catch (Exception e) {
                retries++;
                log.error("Error in Get Ad Extension Report for client " + clientId + " in date " + date + ", Retry: " + retries);

                StringWriter errors = new StringWriter();
                e.printStackTrace(new PrintWriter(errors));
                log.error(errors.toString());
                try {
                    this.sleep(retries*waitBetweenRetries);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
            }
        }
    }
}

class GetKeywordReportThread extends Thread{

    private Long clientId;
    private String locationFile;
    private String date;
    private final static Logger log = Logger.getLogger(GetKeywordReportThread.class);

    GetKeywordReportThread(Long clientId, String locationFile, String date) {
        this.clientId = clientId;
        this.locationFile = locationFile;
        this.date = date;
    }

    public void run(){
        ReportManager rm = new ReportManager();

        int maxRetries = 10;
        Long waitBetweenRetries = 3000L;

        try {
            HashMap<String, String> props = Properties.getEOProperties();

            maxRetries = Integer.parseInt(props.get("retries"));
            waitBetweenRetries = Long.parseLong(props.get("waitBetweenRetries"));
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        int retries = 0;
        boolean finished = false;

        while (retries < maxRetries && !finished){
            try {
                rm.GetKeywordReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                finished = true;
            } catch (Exception e) {

                retries++;
                log.error("Error in Get Keyword Report for client " + clientId + " in date " + date + ", Retry: " + retries);
                StringWriter errors = new StringWriter();
                e.printStackTrace(new PrintWriter(errors));
                log.error(errors.toString());
                try {
                    this.sleep(retries*waitBetweenRetries);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
            }
        }
    }
}

class GetKeywordReportRangeThread extends Thread{

    private Long clientId;
    private String locationFile;
    private String startDate;
    private String endDate;
    private final static Logger log = Logger.getLogger(GetKeywordReportThread.class);

    GetKeywordReportRangeThread(Long clientId, String locationFile, String startDate, String endDate) {
        this.clientId = clientId;
        this.locationFile = locationFile;
        this.startDate = startDate;
        this.endDate = endDate;
    }

    public void run(){
        ReportManager rm = new ReportManager();
        try {
            rm.GetKeywordReportRange(clientId.toString(), locationFile + File.separator, startDate, endDate);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

class GetSegmentedConversionsReportThread extends Thread{

    private Long clientId;
    private String locationFile;
    private String date;
    private final static Logger log = Logger.getLogger(GetAdReportThread.class);

    GetSegmentedConversionsReportThread(Long clientId, String locationFile, String date) {
        this.clientId = clientId;
        this.locationFile = locationFile;
        this.date = date;
    }

    public void run(){
        ReportManager rm = new ReportManager();

        int maxRetries = 10;
        Long waitBetweenRetries = 3000L;

        try {
            HashMap<String, String> props = Properties.getEOProperties();

            maxRetries = Integer.parseInt(props.get("retries"));
            waitBetweenRetries = Long.parseLong(props.get("waitBetweenRetries"));
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

        int retries = 0;
        boolean finished = false;

        while (retries < maxRetries && !finished){

            try {
                rm.GetSegmentedConversionsReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                finished = true;

            } catch (Exception e) {
                retries++;
                log.error("Error in Get Ad Report for client " + clientId + " in date " + date + ", Retry: " + retries);

                StringWriter errors = new StringWriter();
                e.printStackTrace(new PrintWriter(errors));
                log.error(errors.toString());
                try {
                    this.sleep(retries*waitBetweenRetries);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
            }
        }
    }

}

class GetCallReportThread extends Thread{

    private Long clientId;
    private String locationFile;
    private String date;
    private final static Logger log = Logger.getLogger(GetCallReportThread.class);

    GetCallReportThread(Long clientId, String locationFile, String date) {
        this.clientId = clientId;
        this.locationFile = locationFile;
        this.date = date;
    }

    public void run(){
        ReportManager rm = new ReportManager();

        int maxRetries = 10;
        Long waitBetweenRetries = 3000L;

        try {
            HashMap<String, String> props = Properties.getEOProperties();

            maxRetries = Integer.parseInt(props.get("retries"));
            waitBetweenRetries = Long.parseLong(props.get("waitBetweenRetries"));
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        int retries = 0;
        boolean finished = false;

        while (retries < maxRetries && !finished){
            try {
                rm.GetCallsReport(clientId.toString(), locationFile + File.separator + clientId + "-" + date, date);
                finished = true;
            } catch (Exception e) {

                retries++;
                log.error("Error in Get Keyword Report for client " + clientId + " in date " + date + ", Retry: " + retries);
                StringWriter errors = new StringWriter();
                e.printStackTrace(new PrintWriter(errors));
                log.error(errors.toString());
                try {
                    this.sleep(retries*waitBetweenRetries);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
            }
        }
    }
}

class GetCampaignStatsThread extends Thread{

    private Long clientId;

    private ArrayList<CampaignReport> campaignReports;

    GetCampaignStatsThread(Long clientId){
        this.clientId = clientId;
    }

    public ArrayList<CampaignReport> GetCampaignStats(){
        return campaignReports;
    }

    public void run(){

        CampaignManager cm = new CampaignManager();

        ArrayList<CampaignReport> campaignStats = new ArrayList<CampaignReport>();

        cm.SetClientId(this.clientId.toString());
        ArrayList<GA_CampaignStats> stats = cm.GetCampaignStats();
        for (GA_CampaignStats stat : stats) {
            CampaignReport campaignReport = new CampaignReport();
            campaignReport.AdServingOptimizationStatus = stat.AdServingOptimizationStatus;
            campaignReport.BidCeiling = stat.BidCeiling;
            campaignReport.BiddingStrategyType = stat.BiddingStrategyType;
            campaignReport.BidType = stat.BidType;
            campaignReport.BudgetId = stat.BudgetId;
            campaignReport.EndDate = stat.EndDate;
            campaignReport.EnhancedCpcEnabled = stat.EnhancedCpcEnabled;
            campaignReport.FrequencyCapMaxImpressions = stat.FrequencyCapMaxImpressions;
            campaignReport.Id = stat.Id;
            campaignReport.Level = stat.Level;
            campaignReport.Name = stat.Name;
            campaignReport.PricingMode = stat.PricingMode;
            campaignReport.StartDate = stat.StartDate;
            campaignReport.Status = stat.Status;
            campaignReport.TargetContentNetwork = stat.TargetContentNetwork;
            campaignReport.TargetGoogleSearch = stat.TargetGoogleSearch;
            campaignReport.TargetPartnerSearchNetwork = stat.TargetPartnerSearchNetwork;
            campaignReport.TargetSearchNetwork = stat.TargetSearchNetwork;
            campaignReport.TimeUnit = stat.TimeUnit;
            campaignReport.GeoTargetNegativeType = stat.GeoTargetNegativeType;
            campaignReport.GeoTargetPositiveType = stat.GeoTargetPositiveType;
            campaignReport.KeywordMatch = stat.KeywordMatch;
            campaignReport.RealTimeBidding = stat.RealTimeBidding;
            campaignReport.AdvertisingChannelType = stat.AdvertisingChannelType;
            campaignReport.BiddingStrategyId = stat.BiddingStrategyId;
            campaignReport.BiddingStrategyName = stat.BiddingStrategyName;

            campaignStats.add(campaignReport);
        }

        campaignReports = campaignStats;


    }

}

class GetCallsFeedItemsReportThread extends Thread{
    private Long clientId;
    private ArrayList<GA_CallsFeedItem> callsFeedItems;

    GetCallsFeedItemsReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        FeedManager fm = new FeedManager();
        callsFeedItems = fm.GetCallsFeedItemReport(clientId.toString());
    }

    public ArrayList<GA_CallsFeedItem> GetCallsReportThread(){
        return callsFeedItems;
    }
}

class GetTotalReportForClientThread extends Thread{
    private Long clientId;
    private String filePath;

    GetTotalReportForClientThread(Long clientId, String filePath){
        this.clientId = clientId;
        this.filePath = filePath;
    }

    public void run(){
        ReportManager rm = new ReportManager();
        rm.GetTotalReportForClientThreaded(clientId.toString(), filePath);
    }
}

class GetLocationExtensionsFeedItemsReportThread extends Thread{
    private Long clientId;
    private ArrayList<GA_LocationExtensionsFeedItem> locationExtensionsFeedItems;

    GetLocationExtensionsFeedItemsReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        FeedManager fm = new FeedManager();
        locationExtensionsFeedItems = fm.GetLocationExtensionsFeedItemReport(clientId.toString());
    }

    public ArrayList<GA_LocationExtensionsFeedItem> GetLocationExtensionsReportThread(){
        return locationExtensionsFeedItems;
    }

}

class GetSitelinksFeedItemsReportThread extends Thread{
    private Long clientId;
    private ArrayList<GA_SitelinksFeedItem> sitelinksFeedItems;

    GetSitelinksFeedItemsReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        FeedManager fm = new FeedManager();
        sitelinksFeedItems = fm.GetSitelinksFeedItemReport(clientId.toString());
    }

    public ArrayList<GA_SitelinksFeedItem> GetSitelinksFeedItemsReportThread(){
        return sitelinksFeedItems;
    }
}

class GetAdGroupAgeReportThread extends Thread{
    private Long clientId;
    private ArrayList<AdGroupAgeReport> adGroupAgeReports;

    GetAdGroupAgeReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        AdGroupCriterionManager acm = new AdGroupCriterionManager();
        adGroupAgeReports = acm.GetAdGroupAges(clientId.toString());
    }

    public ArrayList<AdGroupAgeReport> GetAdGroupAgeReportThreaded(){
        return adGroupAgeReports;
    }
}

class GetAdGroupGenderReportThread extends Thread{
    private Long clientId;
    private ArrayList<AdGroupGenderReport> adGroupGenderReports;

    GetAdGroupGenderReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        AdGroupCriterionManager acm = new AdGroupCriterionManager();
        adGroupGenderReports = acm.GetAdGroupGenders(clientId.toString());
    }

    public ArrayList<AdGroupGenderReport> GetAdGroupGenderReportThreaded(){
        return adGroupGenderReports;
    }
}

class GetAdGroupInterestReportThread extends Thread{
    private Long clientId;
    private ArrayList<AdGroupInterestReport> adGroupInterestReports;

    GetAdGroupInterestReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        AdGroupCriterionManager acm = new AdGroupCriterionManager();
        adGroupInterestReports = acm.GetAdGroupInterests(clientId.toString());
    }

    public ArrayList<AdGroupInterestReport> GetAdGroupInterestReportsThreaded(){
        return adGroupInterestReports;
    }
}

class GetAdGroupTopicReportThread extends Thread{
    private Long clientId;
    private ArrayList<AdGroupTopicReport> adGroupTopics;

    GetAdGroupTopicReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        AdGroupCriterionManager acm = new AdGroupCriterionManager();
        adGroupTopics = acm.GetAdGroupTopics(clientId.toString());
    }

    public ArrayList<AdGroupTopicReport> GetAdGroupTopicsReport(){
        return adGroupTopics;
    }
}

class GetAdGroupPlacementsReportThread extends Thread{
    private Long clientId;
    private ArrayList<AdGroupPlacementReport> adGroupPlacements;

    GetAdGroupPlacementsReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        AdGroupCriterionManager acm = new AdGroupCriterionManager();
        adGroupPlacements = acm.GetAdGroupPlacements(clientId.toString());
    }

    public ArrayList<AdGroupPlacementReport> GetAdGroupPlacementsReport(){
        return adGroupPlacements;
    }
}

class GetAllFeedsReportThread extends Thread{
    private Long clientId;
    private ArrayList<FeedReport> feedReports;

    GetAllFeedsReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        FeedManager fm = new FeedManager();
        feedReports = fm.GetAllFeedsReport(clientId.toString());
    }

    public ArrayList<FeedReport> GetFeedReports(){
        return feedReports;
    }
}

class GetAccountStatsReportThread extends Thread{
    private Long clientId;
    private AccountReport accountReport;

    GetAccountStatsReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        AccountManager am = new AccountManager();
        accountReport = am.GetAccountReport(clientId.toString());
    }

    public AccountReport GetAccountReport(){
        return accountReport;
    }


}

class GetBudgetReportThread extends Thread{
    private Long clientId;
    private ArrayList<BudgetReport> budgetReports;

    GetBudgetReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        CampaignManager cm = new CampaignManager();
        budgetReports = cm.GetBudgetStats();
    }

    public ArrayList<BudgetReport> GetBudgetReportThreaded(){
        return budgetReports;
    }

}

class GetAdGroupKeywordsReportThread extends Thread{
    private Long clientId;
    private ArrayList<AdGroupKeywordReport> adGroupKeywords;

    GetAdGroupKeywordsReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        AdGroupCriterionManager acm = new AdGroupCriterionManager();
        adGroupKeywords = acm.GetAdGroupKeywords(clientId.toString());
    }

    ArrayList<AdGroupKeywordReport> GetAdGroupKeywordReportThreaded(){
        return adGroupKeywords;
    }

}

class GetImageAdsReportThread extends Thread{
    private Long clientId;
    private ArrayList<ImageAdReport> imageAds;

    GetImageAdsReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        AdsManager adsManager = new AdsManager();
        imageAds = adsManager.GetImageAds(clientId.toString());
    }

    public ArrayList<ImageAdReport> GetImageAdsReportThreaded(){
        return imageAds;
    }
}

class GetMobileImageAdsReportThread extends Thread{
    private Long clientId;
    private ArrayList<MobileImageAdReport> mobileImageAds;

    GetMobileImageAdsReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        AdsManager adsManager = new AdsManager();
        mobileImageAds = adsManager.GetMobileImageAds(clientId.toString());
    }

    public ArrayList<MobileImageAdReport> GetMobileImageAdsReportThreaded(){
        return mobileImageAds;
    }
}

class GetTextAdsReportThread extends Thread{
    private Long clientId;
    private ArrayList<TextAdReport> textAds;

    GetTextAdsReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        AdsManager adsManager = new AdsManager();
        textAds = adsManager.GetTextAds(clientId.toString());
    }

    public ArrayList<TextAdReport> GetTextAdsReportThreaded(){
        return textAds;
    }
}

class GetAdExtensionLocationReportThread extends Thread{


    private Long clientId;

    private ArrayList<AdExtensionLocationReport> adExtensionLocationReports;

    GetAdExtensionLocationReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){

        AdExtensionManager adExtManager = new AdExtensionManager();
        adExtensionLocationReports = adExtManager.GetAdExtensionLocationReport(this.clientId.toString());


    }

    public ArrayList<AdExtensionLocationReport> GetAdExtensionLocationReportsThreaded(){
        return adExtensionLocationReports;
    }
}

class GetSitelinksReportThread extends Thread{


    private Long clientId;

    private ArrayList<SitelinksReport> sitelinksReports;

    GetSitelinksReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){

        AdExtensionManager adExtManager = new AdExtensionManager();
        sitelinksReports = adExtManager.GetFeedItemsSitelinksReport(this.clientId.toString());



    }

    public ArrayList<SitelinksReport> GetSitelinksReportsThreaded(){
        return sitelinksReports;
    }
}

class GetCallsAdExtensionReportThread extends Thread{


    private Long clientId;

    private ArrayList<CallsAdExtensionReport> callsAdExtensionReports;

    GetCallsAdExtensionReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){

        AdExtensionManager adExtManager = new AdExtensionManager();
        callsAdExtensionReports = adExtManager.GetFeedItemsAdExtensionsCallsReport(this.clientId.toString());



    }

    public ArrayList<CallsAdExtensionReport> GetCallsAdExtensionReportsThreaded(){
        return callsAdExtensionReports;
    }
}

class GetLocationExtensionReportThread extends Thread{

    private Long clientId;

    private ArrayList<LocationExtensionReport> locationExtensionReports;

    GetLocationExtensionReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){

        AdExtensionManager adExtManager = new AdExtensionManager();
        locationExtensionReports = adExtManager.GetFeedItemsLocationExtensionReport(this.clientId.toString());



    }

    public ArrayList<LocationExtensionReport> GetLocationExtensionReportsThreaded(){
        return locationExtensionReports;
    }
}

class GetCampaignProximitiesReportThread extends Thread{
    private Long clientId;
    private ArrayList<ProximityReport> proximityReports;

    GetCampaignProximitiesReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        CampaignCriterionManager ccm = new CampaignCriterionManager();
        proximityReports = ccm.GetProximities(this.clientId.toString());
    }

    public ArrayList<ProximityReport> GetProximitiesReportThreaded(){
        return proximityReports;
    }

}

class GetCampaignLocationsReportThread extends Thread{
    private Long clientId;
    private ArrayList<LocationReport> locationReports;

    GetCampaignLocationsReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        CampaignCriterionManager ccm = new CampaignCriterionManager();
        locationReports = ccm.GetLocations(this.clientId.toString());
        LocationCriterionManager lcm = new LocationCriterionManager();
        lcm.SetClientId(this.clientId.toString());
        lcm.getLocationsExtraData(locationReports);
    }

    public ArrayList<LocationReport> GetLocationsReportThreaded(){
        return locationReports;
    }

}

class GetCampaignAdGroupReportThread extends Thread{
    private Long clientId;
    private ArrayList<AdGroupReport> campaignAdGroups;

    GetCampaignAdGroupReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        AdGroupManager adm = new AdGroupManager();
        campaignAdGroups = adm.GetAdGroupStats(this.clientId.toString());
    }

    public ArrayList<AdGroupReport> GetAdGroupReportThreaded(){
        return campaignAdGroups;
    }
}

class GetCampaignKeywordReportThread extends Thread{
    private Long clientId;
    private ArrayList<KeywordReport> campaignKeywords;

    GetCampaignKeywordReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        CampaignCriterionManager ccm = new CampaignCriterionManager();
        campaignKeywords = ccm.GetKeywords(this.clientId.toString(), new ArrayList<String>());
    }

    public ArrayList<KeywordReport> GetKeywordReportThreaded(){
        return campaignKeywords;
    }

}

class GetCampaignAdScheduleReportThread extends Thread{
    private Long clientId;
    private ArrayList<CampaignAdScheduleReport> campaignAdSchedules;

    GetCampaignAdScheduleReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        CampaignCriterionManager ccm = new CampaignCriterionManager();
        campaignAdSchedules = ccm.GetAdSchedules(this.clientId.toString(), new ArrayList<String>());
    }

    public ArrayList<CampaignAdScheduleReport> GetAdScheduleReportThreaded(){
        return campaignAdSchedules;
    }

}

class GetPlatformReportThread extends Thread{
    private Long clientId;
    private ArrayList<PlatformReport> platformReports;

    GetPlatformReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        CampaignTargetingManager ctm = new CampaignTargetingManager();
        platformReports = ctm.GetCampaignDevices(this.clientId.toString());
    }

    public ArrayList<PlatformReport> GetPlatformReportsThreaded(){
        return platformReports;
    }
}

class GetLanguageReportThread extends Thread{
    private Long clientId;
    private ArrayList<LanguageReport> languageReports;

    GetLanguageReportThread(Long clientId){
        this.clientId = clientId;
    }

    public void run(){
        CampaignTargetingManager ctm = new CampaignTargetingManager();
        languageReports = ctm.GetCampaignLanguages(this.clientId.toString());
    }

    public ArrayList<LanguageReport> GetLanguageReportsThreaded(){
        return languageReports;
    }
}

class GetTotalReportClientThread extends Thread{

    private String clientId;
    private String locationFile;

    GetTotalReportClientThread(String clientId, String locationFile){
        this.clientId = clientId;
        this.locationFile = locationFile;
    }

    public void run(){
        ReportManager rm = new ReportManager();
        rm.GetTotalReportForClient(clientId,locationFile);
    }

}


